Full Code of Praytic/youtd2 for AI

main 5471b4b472e7 cached
3046 files
5.3 MB
1.6M tokens
23 symbols
1 requests
Download .txt
Showing preview only (6,198K chars total). Download the full file or copy to clipboard to get everything.
Repository: Praytic/youtd2
Branch: main
Commit: 5471b4b472e7
Files: 3046
Total size: 5.3 MB

Directory structure:
gitextract_l9w5256r/

├── .github/
│   ├── CODEOWNERS
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── RCLONE.md
│   ├── TRANSLATING.md
│   └── workflows/
│       └── github-actions-youtd.yml
├── .gitignore
├── LICENSE
├── README.md
├── addons/
│   ├── com.heroiclabs.nakama/
│   │   ├── Nakama.gd
│   │   ├── Satori/
│   │   │   ├── NakamaEvent.gd
│   │   │   ├── SatoriAPI.gd
│   │   │   ├── SatoriClient.gd
│   │   │   ├── SatoriHttpAdapter.gd
│   │   │   ├── SatoriSession.gd
│   │   │   └── utils/
│   │   │       ├── SatoriAsyncResult.gd
│   │   │       ├── SatoriException.gd
│   │   │       ├── SatoriLogger.gd
│   │   │       └── SatoriSerializer.gd
│   │   ├── Satori.gd
│   │   ├── api/
│   │   │   ├── NakamaAPI.gd
│   │   │   ├── NakamaRTAPI.gd
│   │   │   ├── NakamaRTMessage.gd
│   │   │   ├── NakamaSession.gd
│   │   │   ├── NakamaStorageObjectId.gd
│   │   │   └── NakamaWriteStorageObject.gd
│   │   ├── client/
│   │   │   ├── NakamaClient.gd
│   │   │   └── NakamaHTTPAdapter.gd
│   │   ├── dotnet-utils/
│   │   │   ├── GodotHttpAdapter.cs
│   │   │   ├── GodotLogger.cs
│   │   │   └── GodotWebSocketAdapter.cs
│   │   ├── socket/
│   │   │   ├── NakamaSocket.gd
│   │   │   └── NakamaSocketAdapter.gd
│   │   └── utils/
│   │       ├── NakamaAsyncResult.gd
│   │       ├── NakamaException.gd
│   │       ├── NakamaLogger.gd
│   │       ├── NakamaMultiplayerBridge.gd
│   │       ├── NakamaMultiplayerPeer.gd
│   │       └── NakamaSerializer.gd
│   └── nakama-webrtc/
│       ├── LICENSE.txt
│       └── OnlineMatch.gd
├── assets/
│   ├── LICENSE.md
│   ├── README.md
│   ├── creeps/
│   │   ├── README.md
│   │   └── orc/
│   │       ├── air/
│   │       │   ├── fly_E.png.import
│   │       │   ├── fly_N.png.import
│   │       │   ├── fly_NE.png.import
│   │       │   ├── fly_NW.png.import
│   │       │   ├── fly_S.png.import
│   │       │   ├── fly_SE.png.import
│   │       │   ├── fly_SW.png.import
│   │       │   ├── fly_W.png.import
│   │       │   ├── metadata.csv
│   │       │   └── metadata.csv.import
│   │       ├── boss/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       ├── champion/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       ├── mass/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       └── normal/
│   │           ├── death_E.png.import
│   │           ├── death_N.png.import
│   │           ├── death_S.png.import
│   │           ├── death_W.png.import
│   │           ├── metadata.csv
│   │           ├── metadata.csv.import
│   │           ├── slow_run_E.png.import
│   │           ├── slow_run_N.png.import
│   │           ├── slow_run_S.png.import
│   │           └── slow_run_W.png.import
│   ├── effects/
│   │   ├── arrow.png.import
│   │   ├── bdragon/
│   │   │   ├── README.md
│   │   │   ├── ancient_protector_missile_293.png.import
│   │   │   ├── animated_dead_target_102.png.import
│   │   │   ├── apply_potion_537.png.import
│   │   │   ├── arcane_tower_attack_024.png.import
│   │   │   ├── avatar_caster_10.png.import
│   │   │   ├── banshee_missile_487.png.import
│   │   │   ├── blink_target_720.png.import
│   │   │   ├── blood_splatter_376.png.import
│   │   │   ├── build_tower_648.png.import
│   │   │   ├── charm_target_703.png.import
│   │   │   ├── cloud_of_fog_382.png.import
│   │   │   ├── cloud_of_fog_small_428.png.import
│   │   │   ├── cripple_target_198.png.import
│   │   │   ├── crushing_wave_damage_584.png.import
│   │   │   ├── crypt_fiend_eggsack_528.png.import
│   │   │   ├── cyclone_target_269.png.import
│   │   │   ├── death_and_decay_71.png.import
│   │   │   ├── death_coil_special_728.png.import
│   │   │   ├── devour_509.png.import
│   │   │   ├── dispel_magic_target_456.png.import
│   │   │   ├── doom_death_451.png.import
│   │   │   ├── faerie_dragon_missile_482.png.import
│   │   │   ├── firelord_death_explode_77.png.import
│   │   │   ├── flame_strike_embers_702.png.import
│   │   │   ├── flower_aura_655.png.import
│   │   │   ├── frag_boom_spawn_426.png.import
│   │   │   ├── freezing_breath_519.png.import
│   │   │   ├── frost_armor_damage_474.png.import
│   │   │   ├── frost_bolt_missile_063.png.import
│   │   │   ├── glaive_746.png.import
│   │   │   ├── gold_credit_673.png.import
│   │   │   ├── gold_credit_88.png.import
│   │   │   ├── healing_wave_target_453.png.import
│   │   │   ├── holy_bolt_241.png.import
│   │   │   ├── immolation_damage_541.png.import
│   │   │   ├── impale_hit_target_529.png.import
│   │   │   ├── impale_target_dust_025.png.import
│   │   │   ├── incinerate_76.png.import
│   │   │   ├── keeper_grove_missile_297.png.import
│   │   │   ├── level_up_455.png.import
│   │   │   ├── mana_burn_target_388.png.import
│   │   │   ├── mana_shield_026.png.import
│   │   │   ├── mass_teleport_caster_335.png.import
│   │   │   ├── mass_teleport_target_315.png.import
│   │   │   ├── mirror_image_caster_711.png.import
│   │   │   ├── moonwell_target_584.png.import
│   │   │   ├── ne_cancel_death_672.png.import
│   │   │   ├── ne_death_612.png.import
│   │   │   ├── placeholder_481.png.import
│   │   │   ├── polymorph_target_735.png.import
│   │   │   ├── projectile_explosion_299.png.import
│   │   │   ├── purge_buff_target_195.png.import
│   │   │   ├── quillspray_747.png.import
│   │   │   ├── raise_skeleton_624.png.import
│   │   │   ├── replenish_mana_334.png.import
│   │   │   ├── revive_human_623.png.import
│   │   │   ├── roar_506.png.import
│   │   │   ├── roots_235.png.import
│   │   │   ├── shackle_439.png.import
│   │   │   ├── shockwave_missile_440.png.import
│   │   │   ├── silence_area_611.png.import
│   │   │   ├── small_flame_spawn_240.png.import
│   │   │   ├── spell_aiil_452.png.import
│   │   │   ├── spell_ailb_723.png.import
│   │   │   ├── spell_aima_194.png.import
│   │   │   ├── spell_aire_174.png.import
│   │   │   ├── spell_aiso_295.png.import
│   │   │   ├── spell_alim_136.png.import
│   │   │   ├── spell_breaker_target_613.png.import
│   │   │   ├── spirit_link_target_175.png.import
│   │   │   ├── stampede_missile_death_63.png.import
│   │   │   ├── starfall_target_257.png.import
│   │   │   ├── thunder_clap_466.png.import
│   │   │   ├── undead_dissipate_633.png.import
│   │   │   ├── upgrade_tower_016.png.import
│   │   │   ├── vampiric_aura_199.png.import
│   │   │   ├── voodoo_aura_182.png.import
│   │   │   ├── warstomp_caster_536.png.import
│   │   │   ├── wind_shear_559.png.import
│   │   │   ├── wisp_explode_003.png.import
│   │   │   ├── ziggurat_frost_missile_325.png.import
│   │   │   └── zombify_target_274.png.import
│   │   ├── death_explode.png.import
│   │   ├── lightning_long.png.import
│   │   └── stun.png.import
│   ├── fonts/
│   │   ├── Friz Quadrata Std Medium.otf.import
│   │   └── NotoSansSC-Medium.ttf.import
│   ├── hud/
│   │   ├── bitmaps/
│   │   │   ├── circle_bitmap_100x100.png.import
│   │   │   └── circle_bitmap_256x256.png.import
│   │   ├── checkbox.png.import
│   │   ├── circle_bitmap_256x256.png.import
│   │   ├── darkness_face.png.import
│   │   ├── element_progress_circle.png.import
│   │   ├── horadric_cube.png.import
│   │   ├── hud_atlas.png.import
│   │   ├── misc2.png.import
│   │   ├── misc3.png.import
│   │   ├── misc3_s.png.import
│   │   ├── misc4.png.import
│   │   └── tranquility_face.png.import
│   ├── icons/
│   │   ├── amulets.png.import
│   │   ├── animals.png.import
│   │   ├── armor.png.import
│   │   ├── blunt_weapons.png.import
│   │   ├── books.png.import
│   │   ├── bows.png.import
│   │   ├── cannons.png.import
│   │   ├── clubs.png.import
│   │   ├── creep_icons_atlas.png.import
│   │   ├── daggers.png.import
│   │   ├── dioramas.png.import
│   │   ├── electricity.png.import
│   │   ├── elements.png.import
│   │   ├── faces.png.import
│   │   ├── fire.png.import
│   │   ├── food.png.import
│   │   ├── furniture.png.import
│   │   ├── gems.png.import
│   │   ├── generic_icons.png.import
│   │   ├── gloves.png.import
│   │   ├── helmets.png.import
│   │   ├── holy.png.import
│   │   ├── hud.png.import
│   │   ├── magic.png.import
│   │   ├── masks.png.import
│   │   ├── mechanical.png.import
│   │   ├── misc.png.import
│   │   ├── orbs.png.import
│   │   ├── plants.png.import
│   │   ├── potion_icons_m.png.import
│   │   ├── rings.png.import
│   │   ├── rockets.png.import
│   │   ├── scrolls.png.import
│   │   ├── shields.png.import
│   │   ├── spears.png.import
│   │   ├── statues.png.import
│   │   ├── staves.png.import
│   │   ├── swords.png.import
│   │   ├── tier_icons_m.png.import
│   │   ├── tower_icons_m.png.import
│   │   ├── tower_variations.png.import
│   │   ├── trinkets.png.import
│   │   ├── undead.png.import
│   │   └── weapons_misc.png.import
│   ├── misc/
│   │   ├── autocast_automode_particle.png.import
│   │   ├── cast_cursor.png.import
│   │   ├── circle_01.png.import
│   │   ├── circle_02.png.import
│   │   ├── circle_03.png.import
│   │   ├── circle_04.png.import
│   │   ├── circle_05.png.import
│   │   ├── creep_blood_pool.png.import
│   │   ├── icob_min.png.import
│   │   ├── icob_ultra_wide.png.import
│   │   ├── icon.png.import
│   │   ├── potion_drop_animation.png.import
│   │   └── projectile.png.import
│   ├── secrets/
│   │   ├── badwords.csv.import
│   │   └── secrets.csv.import
│   ├── sfx/
│   │   ├── 161654__qubodup__war-game-battle-level-up-remix.ogg.import
│   │   ├── 202147__qubodup__enchant.ogg.import
│   │   ├── 411177__silverillusionist__pick-up-item-1-short.ogg.import
│   │   ├── 420676__sypherzent__spell-cast-buff-high-tone.ogg.import
│   │   ├── 442827__qubodup__fireball.ogg.import
│   │   ├── 442903__qubodup__slash-remix.ogg.import
│   │   ├── 541478__eminyildirim__magic-fire-spell-impact-punch.ogg.import
│   │   ├── 562292__colorscrimsontears__heal-rpg.ogg.import
│   │   ├── 649359__sonofxaudio__sword_water01.ogg.import
│   │   ├── 665082__sunflora__thud.ogg.import
│   │   ├── 682635__bastianhallo__magic-spell.ogg.import
│   │   ├── 683044__brettrader__stomp-soft.ogg.import
│   │   ├── 714258__qubodup__cloud-poof.ogg.import
│   │   ├── 734247__noisyredfox__coins3.ogg.import
│   │   ├── 738438__qubodup__orc-grunt-2.ogg.import
│   │   ├── 745156__tigreplayz__blast-explosion.ogg.import
│   │   ├── DoKashiteru_healspell1.ogg.import
│   │   ├── DoKashiteru_healspell2.ogg.import
│   │   ├── DoKashiteru_healspell3.ogg.import
│   │   ├── README.md
│   │   ├── UI_Electric_01.ogg.import
│   │   ├── artisticdude_freeze.ogg.import
│   │   ├── attribution.csv
│   │   ├── attribution.csv.import
│   │   ├── bart_foom_0.ogg.import
│   │   ├── copyc4t_Archers-shooting.ogg.import
│   │   ├── kevl_level_up.ogg.import
│   │   ├── little_robot_Spell_00.ogg.import
│   │   ├── little_robot_Spell_01.ogg.import
│   │   ├── little_robot_UI_Electric_00.ogg.import
│   │   ├── little_robot_UI_Electric_01.ogg.import
│   │   ├── little_robot_Whoosh_Electric_00.ogg.import
│   │   ├── little_robot_Whoosh_Electric_01.ogg.import
│   │   ├── little_robot_Whoosh_Electric_02.ogg.import
│   │   ├── little_robot_Whoosh_Electric_03.ogg.import
│   │   ├── machel_baradari_jump.wav.import
│   │   ├── michel_baradari_jump.ogg.import
│   │   ├── michel_baradari_jump.wav.import
│   │   ├── michel_baradari_lava.ogg.import
│   │   ├── michel_baradari_teleport.ogg.import
│   │   ├── p0ss_confusion.ogg.import
│   │   ├── p0ss_curse5.ogg.import
│   │   ├── p0ss_enchant.ogg.import
│   │   ├── p0ss_enchant2.ogg.import
│   │   ├── p0ss_explode2.ogg.import
│   │   ├── p0ss_explode4.ogg.import
│   │   ├── p0ss_freeze2.ogg.import
│   │   ├── p0ss_heal.ogg.import
│   │   ├── p0ss_pestilence.ogg.import
│   │   ├── p0ss_sand.ogg.import
│   │   ├── p0ss_shot.ogg.import
│   │   ├── p0ss_spell.ogg.import
│   │   ├── p0ss_steam.ogg.import
│   │   ├── p0ss_teleport.ogg.import
│   │   ├── p0ss_warp.ogg.import
│   │   ├── p0ss_warp2.ogg.import
│   │   ├── p0ss_warp3.ogg.import
│   │   ├── p0ss_water.ogg.import
│   │   ├── p0ss_zap.ogg.import
│   │   ├── p0ss_zap10.ogg.import
│   │   ├── p0ss_zap5a.ogg.import
│   │   ├── spit_01.ogg.import
│   │   ├── unknown_attack_sound1.ogg.import
│   │   ├── unknown_fire_attack1.ogg.import
│   │   ├── unknown_iceball.ogg.import
│   │   ├── unknown_iron_attack1.ogg.import
│   │   ├── unknown_swosh-08.ogg.import
│   │   └── unknown_swosh-11.ogg.import
│   ├── texts/
│   │   ├── README.md
│   │   ├── texts.csv.import
│   │   ├── texts_history.csv
│   │   └── texts_history.csv.import
│   ├── tiles/
│   │   ├── License.txt
│   │   ├── README.md
│   │   ├── barrels.png.import
│   │   ├── bridges.png.import
│   │   ├── chairs.png.import
│   │   ├── chests.png.import
│   │   ├── empty_tiles.png.import
│   │   ├── floor.png.import
│   │   ├── floor1_walls.png.import
│   │   ├── planks.png.import
│   │   ├── spiral_stairs.png.import
│   │   ├── stairs.png.import
│   │   ├── stone_columns.png.import
│   │   ├── stone_walls.png.import
│   │   ├── tables.png.import
│   │   ├── wooden_pile.png.import
│   │   └── wooden_supports.png.import
│   ├── tiles_decoration/
│   │   ├── bushes1.png.import
│   │   ├── column_overgrown.png.import
│   │   ├── leaves1.png.import
│   │   ├── stones1.png.import
│   │   ├── stones2.png.import
│   │   ├── stones3.png.import
│   │   ├── trees1.png.import
│   │   ├── trees2.png.import
│   │   ├── vines1.png.import
│   │   ├── vines2.png.import
│   │   ├── vines3.png.import
│   │   ├── vines4.png.import
│   │   ├── vines5.png.import
│   │   ├── vines6.png.import
│   │   ├── vines7.png.import
│   │   └── wall_vines1.png.import
│   ├── tower_sprites/
│   │   ├── astral_common.png.import
│   │   ├── astral_rare.png.import
│   │   ├── astral_uncommon.png.import
│   │   ├── astral_unique.png.import
│   │   ├── darkness_common.png.import
│   │   ├── darkness_rare.png.import
│   │   ├── darkness_uncommon.png.import
│   │   ├── darkness_unique.png.import
│   │   ├── fire_common.png.import
│   │   ├── fire_rare.png.import
│   │   ├── fire_uncommon.png.import
│   │   ├── fire_unique.png.import
│   │   ├── ice_common.png.import
│   │   ├── ice_rare.png.import
│   │   ├── ice_uncommon.png.import
│   │   ├── ice_unique.png.import
│   │   ├── iron_common.png.import
│   │   ├── iron_rare.png.import
│   │   ├── iron_uncommon.png.import
│   │   ├── iron_unique.png.import
│   │   ├── nature_common.png.import
│   │   ├── nature_rare.png.import
│   │   ├── nature_uncommon.png.import
│   │   ├── nature_unique.png.import
│   │   ├── storm_common.png.import
│   │   ├── storm_rare.png.import
│   │   ├── storm_uncommon.png.import
│   │   └── storm_unique.png.import
│   └── tutorial_pictures/
│       ├── README.md
│       ├── build_tower.png.import
│       ├── item_drop.png.import
│       ├── research.png.import
│       ├── research_element.png.import
│       ├── resource_panel.png.import
│       ├── roll_towers.png.import
│       ├── tower_info.png.import
│       ├── tower_level.png.import
│       ├── tower_mouse_over.png.import
│       ├── tower_stash.png.import
│       ├── transform.png.import
│       ├── upgrade.png.import
│       └── wave_finish.png.import
├── build/
│   ├── README.md
│   ├── linux/
│   │   └── README.md
│   ├── macos/
│   │   └── README.md
│   ├── web/
│   │   └── full-size.html
│   └── windows/
│       └── README.md
├── data/
│   ├── README.md
│   ├── ability_properties.csv
│   ├── ability_properties.csv.import
│   ├── aura_properties.csv
│   ├── aura_properties.csv.import
│   ├── autocast_properties.csv
│   ├── autocast_properties.csv.import
│   ├── builder_properties.csv
│   ├── builder_properties.csv.import
│   ├── exp_for_level.csv
│   ├── exp_for_level.csv.import
│   ├── hints/
│   │   ├── advanced.csv
│   │   ├── advanced.csv.import
│   │   ├── basic.csv.import
│   │   ├── basics.csv
│   │   ├── basics.csv.import
│   │   ├── chat_commands.csv
│   │   ├── chat_commands.csv.import
│   │   ├── creep_specials.csv
│   │   ├── creep_specials.csv.import
│   │   ├── creeps.csv
│   │   ├── creeps.csv.import
│   │   ├── items.csv
│   │   ├── items.csv.import
│   │   ├── towers.csv
│   │   ├── towers.csv.import
│   │   ├── tutorial.csv
│   │   └── tutorial.csv.import
│   ├── item_properties.csv
│   ├── item_properties.csv.import
│   ├── mission_properties.csv
│   ├── mission_properties.csv.import
│   ├── player_exp_for_level.csv
│   ├── player_exp_for_level.csv.import
│   ├── recipe_properties.csv
│   ├── recipe_properties.csv.import
│   ├── tower_properties.csv
│   ├── tower_properties.csv.import
│   ├── wave_special_properties.csv
│   ├── wave_special_properties.csv.import
│   ├── wisdom_upgrades.csv
│   └── wisdom_upgrades.csv.import
├── export_presets.cfg
├── project.godot
├── rclone-filter
├── resources/
│   ├── README.md
│   ├── button_groups/
│   │   ├── element_filter_button_group.tres
│   │   ├── interface_size_setting_button_group.tres
│   │   ├── item_type_filter_button_group.tres
│   │   ├── menu_cards_button_group.tres
│   │   ├── right_panel_button_group.tres
│   │   └── speed_button_group.tres
│   ├── icons/
│   │   ├── amulets/
│   │   │   ├── amulet_01.tres
│   │   │   ├── amulet_02.tres
│   │   │   ├── amulet_03.tres
│   │   │   └── amulet_04.tres
│   │   ├── animals/
│   │   │   ├── bat_01.tres
│   │   │   ├── bat_02.tres
│   │   │   ├── bat_03.tres
│   │   │   ├── cow.tres
│   │   │   ├── dragon_01.tres
│   │   │   ├── dragon_02.tres
│   │   │   ├── dragon_03.tres
│   │   │   ├── dragon_04.tres
│   │   │   ├── dragon_05.tres
│   │   │   ├── fish_01.tres
│   │   │   ├── fish_02.tres
│   │   │   ├── fish_03.tres
│   │   │   ├── fish_04.tres
│   │   │   ├── mech_toad.tres
│   │   │   ├── piglet_warrior.tres
│   │   │   ├── rabbit.tres
│   │   │   ├── rooster_warrior.tres
│   │   │   ├── spider_01.tres
│   │   │   ├── spider_02.tres
│   │   │   ├── spider_03.tres
│   │   │   └── wing.tres
│   │   ├── armor/
│   │   │   ├── chest_plate.tres
│   │   │   ├── chest_plate_with_spike.tres
│   │   │   ├── coat.tres
│   │   │   ├── lightning_boot.tres
│   │   │   ├── vest_01.tres
│   │   │   ├── vest_02.tres
│   │   │   ├── vest_03.tres
│   │   │   └── vest_04.tres
│   │   ├── blunt_weapons/
│   │   │   ├── hammer_01.tres
│   │   │   ├── hammer_02.tres
│   │   │   ├── hammer_03.tres
│   │   │   ├── hammer_04.tres
│   │   │   ├── wood_01.tres
│   │   │   ├── wood_02.tres
│   │   │   ├── wood_03.tres
│   │   │   └── wood_04.tres
│   │   ├── books/
│   │   │   ├── book_01.tres
│   │   │   ├── book_02.tres
│   │   │   ├── book_03.tres
│   │   │   ├── book_04.tres
│   │   │   ├── book_05.tres
│   │   │   ├── book_06.tres
│   │   │   ├── book_07.tres
│   │   │   ├── book_08.tres
│   │   │   ├── book_09.tres
│   │   │   ├── book_10.tres
│   │   │   ├── book_11.tres
│   │   │   ├── note_01.tres
│   │   │   ├── note_02.tres
│   │   │   ├── note_03.tres
│   │   │   └── note_04.tres
│   │   ├── bows/
│   │   │   ├── arrow_01.tres
│   │   │   ├── arrow_02.tres
│   │   │   ├── bow_01.tres
│   │   │   ├── bow_02.tres
│   │   │   ├── bow_03.tres
│   │   │   ├── bow_04.tres
│   │   │   ├── bow_05.tres
│   │   │   └── bow_06.tres
│   │   ├── cannons/
│   │   │   ├── cannon_01.tres
│   │   │   ├── cannon_02.tres
│   │   │   ├── cannon_03.tres
│   │   │   ├── cannon_04.tres
│   │   │   ├── cannon_05.tres
│   │   │   ├── cannon_06.tres
│   │   │   ├── cannon_07.tres
│   │   │   ├── cannon_08.tres
│   │   │   ├── gun_01.tres
│   │   │   └── gun_02.tres
│   │   ├── clubs/
│   │   │   ├── club_01.tres
│   │   │   ├── club_02.tres
│   │   │   ├── club_03.tres
│   │   │   ├── club_04.tres
│   │   │   ├── club_04_without_handle.tres
│   │   │   └── club_glowing.tres
│   │   ├── creep_icons/
│   │   │   ├── challenge_challenge_boss.tres
│   │   │   ├── challenge_challenge_mass.tres
│   │   │   ├── humanoid_air.tres
│   │   │   ├── humanoid_boss.tres
│   │   │   ├── humanoid_champion.tres
│   │   │   ├── humanoid_mass.tres
│   │   │   ├── humanoid_normal.tres
│   │   │   ├── magic_air.tres
│   │   │   ├── magic_boss.tres
│   │   │   ├── magic_champion.tres
│   │   │   ├── magic_mass.tres
│   │   │   ├── magic_normal.tres
│   │   │   ├── nature_air.tres
│   │   │   ├── nature_boss.tres
│   │   │   ├── nature_champion.tres
│   │   │   ├── nature_mass.tres
│   │   │   ├── nature_normal.tres
│   │   │   ├── orc_air.tres
│   │   │   ├── orc_boss.tres
│   │   │   ├── orc_champion.tres
│   │   │   ├── orc_mass.tres
│   │   │   ├── orc_normal.tres
│   │   │   ├── undead_air.tres
│   │   │   ├── undead_boss.tres
│   │   │   ├── undead_champion.tres
│   │   │   ├── undead_mass.tres
│   │   │   └── undead_normal.tres
│   │   ├── daggers/
│   │   │   ├── dagger_01.tres
│   │   │   ├── dagger_02.tres
│   │   │   ├── dagger_03.tres
│   │   │   ├── dagger_04.tres
│   │   │   ├── dagger_05.tres
│   │   │   ├── dagger_06.tres
│   │   │   ├── dagger_07.tres
│   │   │   ├── dagger_08.tres
│   │   │   └── dagger_09.tres
│   │   ├── dioramas/
│   │   │   ├── book_display.tres
│   │   │   ├── church.tres
│   │   │   ├── fountain.tres
│   │   │   ├── mountain.tres
│   │   │   └── pyramid.tres
│   │   ├── electricity/
│   │   │   ├── electricity_blue.tres
│   │   │   ├── electricity_yellow.tres
│   │   │   ├── lightning_circle_cyan.tres
│   │   │   ├── lightning_circle_white.tres
│   │   │   ├── lightning_glowing.tres
│   │   │   └── thunderstorm.tres
│   │   ├── elements/
│   │   │   ├── astral.tres
│   │   │   ├── darkness.tres
│   │   │   ├── fire.tres
│   │   │   ├── ice.tres
│   │   │   ├── iron.tres
│   │   │   ├── nature.tres
│   │   │   └── storm.tres
│   │   ├── faces/
│   │   │   ├── green_demon.tres
│   │   │   ├── man_01.tres
│   │   │   ├── man_02.tres
│   │   │   ├── man_03.tres
│   │   │   ├── man_04.tres
│   │   │   ├── man_05.tres
│   │   │   ├── mech_zombie.tres
│   │   │   ├── orc_01.tres
│   │   │   ├── orc_02.tres
│   │   │   ├── sleeping_leaf_spirit.tres
│   │   │   ├── woman_01.tres
│   │   │   ├── woman_02.tres
│   │   │   └── woman_03.tres
│   │   ├── fire/
│   │   │   ├── burning_cloth.tres
│   │   │   ├── fire_bowl_01.tres
│   │   │   ├── fire_bowl_02.tres
│   │   │   ├── fire_bowl_03.tres
│   │   │   ├── fire_in_cup.tres
│   │   │   ├── flame_blue.tres
│   │   │   ├── flame_blue_glowing.tres
│   │   │   ├── flame_purple.tres
│   │   │   └── torch.tres
│   │   ├── food/
│   │   │   ├── barrel.tres
│   │   │   ├── beer_01.tres
│   │   │   ├── beer_02.tres
│   │   │   ├── lard.tres
│   │   │   ├── pork.tres
│   │   │   ├── pork_without_plate.tres
│   │   │   └── poultry.tres
│   │   ├── furniture/
│   │   │   ├── artifact_of_skadi.tres
│   │   │   ├── artifact_on_pedestal.tres
│   │   │   ├── bed.tres
│   │   │   ├── chest.tres
│   │   │   ├── exploding_mirror.tres
│   │   │   ├── furniture.tres
│   │   │   ├── stool.tres
│   │   │   ├── throne.tres
│   │   │   └── wooden_stand_with_nail.tres
│   │   ├── gems/
│   │   │   ├── crystal.tres
│   │   │   ├── earring_01.tres
│   │   │   ├── earring_02.tres
│   │   │   ├── earring_03.tres
│   │   │   ├── earring_04.tres
│   │   │   ├── earring_05.tres
│   │   │   ├── gem_01.tres
│   │   │   ├── gem_02.tres
│   │   │   ├── gem_03.tres
│   │   │   ├── gem_04.tres
│   │   │   ├── gem_05.tres
│   │   │   ├── gem_06.tres
│   │   │   ├── gem_07.tres
│   │   │   ├── stone_01.tres
│   │   │   ├── stone_02.tres
│   │   │   ├── stone_03.tres
│   │   │   └── stone_04.tres
│   │   ├── generic_icons/
│   │   │   ├── README.md
│   │   │   ├── abdominal_armor.tres
│   │   │   ├── alien_skull.tres
│   │   │   ├── alligator_clip.tres
│   │   │   ├── amber_mosquito.tres
│   │   │   ├── angel_outfit.tres
│   │   │   ├── angel_wings.tres
│   │   │   ├── animal_skull.tres
│   │   │   ├── ankh.tres
│   │   │   ├── aquarius.tres
│   │   │   ├── aries.tres
│   │   │   ├── armor_vest.tres
│   │   │   ├── atomic_slashes.tres
│   │   │   ├── azul_flake.tres
│   │   │   ├── barbute.tres
│   │   │   ├── barefoot.tres
│   │   │   ├── bat_mask.tres
│   │   │   ├── beard.tres
│   │   │   ├── biceps.tres
│   │   │   ├── burning_dot.tres
│   │   │   ├── burning_meteor.tres
│   │   │   ├── charm.tres
│   │   │   ├── chest_armor.tres
│   │   │   ├── cog.tres
│   │   │   ├── egg.tres
│   │   │   ├── electric.tres
│   │   │   ├── energy_breath.tres
│   │   │   ├── fire_dash.tres
│   │   │   ├── flame.tres
│   │   │   ├── foot_trip.tres
│   │   │   ├── ghost.tres
│   │   │   ├── gold_bar.tres
│   │   │   ├── hammer_drop.tres
│   │   │   ├── holy_grail.tres
│   │   │   ├── horned_helm.tres
│   │   │   ├── hourglass.tres
│   │   │   ├── knocked_out_stars.tres
│   │   │   ├── liberty_wing.tres
│   │   │   ├── meat.tres
│   │   │   ├── mighty_force.tres
│   │   │   ├── mine_explosion.tres
│   │   │   ├── moebius_trefoil.tres
│   │   │   ├── omega.tres
│   │   │   ├── open_wound.tres
│   │   │   ├── ophiucus.tres
│   │   │   ├── orc_head.tres
│   │   │   ├── over_infinity.tres
│   │   │   ├── perpendicular_rings.tres
│   │   │   ├── pisces.tres
│   │   │   ├── poison_gas.tres
│   │   │   ├── pokecog.tres
│   │   │   ├── polar_star.tres
│   │   │   ├── rolling_energy.tres
│   │   │   ├── root_tip.tres
│   │   │   ├── round_potion.tres
│   │   │   ├── rss.tres
│   │   │   ├── semi_closed_eye.tres
│   │   │   ├── shiny_omega.tres
│   │   │   ├── spell_book.tres
│   │   │   ├── spider_web.tres
│   │   │   ├── sprint.tres
│   │   │   ├── star_swirl.tres
│   │   │   ├── triple_scratches.tres
│   │   │   ├── turtle_shell.tres
│   │   │   └── wolf_howl.tres
│   │   ├── gloves/
│   │   │   ├── curse.tres
│   │   │   ├── gloves_01.tres
│   │   │   ├── gloves_02.tres
│   │   │   ├── gloves_03.tres
│   │   │   ├── gloves_04.tres
│   │   │   ├── gloves_05.tres
│   │   │   ├── gloves_06.tres
│   │   │   ├── gloves_07.tres
│   │   │   ├── gloves_08.tres
│   │   │   ├── heal.tres
│   │   │   └── steal.tres
│   │   ├── helmets/
│   │   │   ├── crown_01.tres
│   │   │   ├── crown_02.tres
│   │   │   ├── crown_03.tres
│   │   │   ├── helmet_01.tres
│   │   │   ├── helmet_02.tres
│   │   │   ├── helmet_03.tres
│   │   │   ├── helmet_04.tres
│   │   │   ├── helmet_05.tres
│   │   │   ├── helmet_06.tres
│   │   │   ├── helmet_07.tres
│   │   │   ├── helmet_08.tres
│   │   │   ├── wizard_hat_01.tres
│   │   │   └── wizard_hat_02.tres
│   │   ├── holy/
│   │   │   ├── altar.tres
│   │   │   ├── axe.tres
│   │   │   ├── cross_01.tres
│   │   │   ├── cross_02.tres
│   │   │   ├── cross_03.tres
│   │   │   ├── orb.tres
│   │   │   ├── tombstone.tres
│   │   │   └── white_trinket.tres
│   │   ├── hud/
│   │   │   ├── dice.tres
│   │   │   ├── gem_all_rarities.tres
│   │   │   ├── gem_common.tres
│   │   │   ├── gem_rare.tres
│   │   │   ├── gem_uncommon.tres
│   │   │   ├── gem_unique.tres
│   │   │   ├── gold.tres
│   │   │   ├── item_stash.tres
│   │   │   ├── knowledge_tome.tres
│   │   │   ├── oils.tres
│   │   │   ├── recipe_distill.tres
│   │   │   ├── recipe_perfect.tres
│   │   │   ├── recipe_reassemble.tres
│   │   │   ├── recipe_rebrew.tres
│   │   │   ├── research_elements.tres
│   │   │   ├── tower_food.tres
│   │   │   └── tower_stash.tres
│   │   ├── magic/
│   │   │   ├── bowl_01.tres
│   │   │   ├── bowl_02.tres
│   │   │   ├── claw_01.tres
│   │   │   ├── claw_02.tres
│   │   │   ├── claw_03.tres
│   │   │   ├── claw_04.tres
│   │   │   ├── eye.tres
│   │   │   ├── eye_blue.tres
│   │   │   ├── eyes_many.tres
│   │   │   ├── fire.tres
│   │   │   ├── lantern.tres
│   │   │   ├── lock_01.tres
│   │   │   ├── lock_02.tres
│   │   │   ├── lock_03.tres
│   │   │   ├── lock_04.tres
│   │   │   ├── magic_stone.tres
│   │   │   └── magic_stone_green.tres
│   │   ├── masks/
│   │   │   ├── mask_01.tres
│   │   │   ├── mask_02.tres
│   │   │   ├── mask_03.tres
│   │   │   ├── mask_04.tres
│   │   │   ├── mask_05.tres
│   │   │   ├── mask_06.tres
│   │   │   └── mask_07.tres
│   │   ├── mechanical/
│   │   │   ├── alchemy_kit_01.tres
│   │   │   ├── alchemy_kit_02.tres
│   │   │   ├── alchemy_kit_03.tres
│   │   │   ├── battery.tres
│   │   │   ├── black_gold_calculator.tres
│   │   │   ├── circuit_board.tres
│   │   │   ├── compass.tres
│   │   │   ├── factory_fumes.tres
│   │   │   ├── factory_gears.tres
│   │   │   ├── gold_machine.tres
│   │   │   ├── lamp.tres
│   │   │   ├── mech_badge.tres
│   │   │   └── mech_umbrella.tres
│   │   ├── misc/
│   │   │   ├── balls_01.tres
│   │   │   ├── balls_02.tres
│   │   │   ├── balls_03.tres
│   │   │   ├── cauldron.tres
│   │   │   ├── flag_01.tres
│   │   │   ├── flag_02.tres
│   │   │   ├── flag_03.tres
│   │   │   ├── gold_cart.tres
│   │   │   ├── grenade.tres
│   │   │   ├── poison_01.tres
│   │   │   ├── poison_02.tres
│   │   │   ├── quiver.tres
│   │   │   ├── red_knight.tres
│   │   │   ├── spiky_totem_01.tres
│   │   │   ├── spiky_totem_02.tres
│   │   │   ├── teapot_01.tres
│   │   │   ├── teapot_02.tres
│   │   │   ├── teapot_03.tres
│   │   │   ├── teapot_04.tres
│   │   │   ├── toolbox_01.tres
│   │   │   └── toolbox_02.tres
│   │   ├── orbs/
│   │   │   ├── moon.tres
│   │   │   ├── orb_fire.tres
│   │   │   ├── orb_green.tres
│   │   │   ├── orb_ice.tres
│   │   │   ├── orb_ice_melting.tres
│   │   │   ├── orb_molten.tres
│   │   │   ├── orb_molten_dull.tres
│   │   │   ├── orb_shadow.tres
│   │   │   └── orb_small.tres
│   │   ├── plants/
│   │   │   ├── branch_01.tres
│   │   │   ├── branch_02.tres
│   │   │   ├── flower_01.tres
│   │   │   ├── flower_02.tres
│   │   │   ├── flower_03.tres
│   │   │   ├── flower_04.tres
│   │   │   ├── flower_05.tres
│   │   │   ├── flower_06.tres
│   │   │   ├── leaf_01.tres
│   │   │   ├── leaf_02.tres
│   │   │   ├── leaf_03.tres
│   │   │   ├── plant_in_pot.tres
│   │   │   ├── stump.tres
│   │   │   └── tree.tres
│   │   ├── potions/
│   │   │   ├── beaker_01.tres
│   │   │   ├── beaker_02.tres
│   │   │   ├── beaker_03.tres
│   │   │   ├── potion_01.tres
│   │   │   ├── potion_02.tres
│   │   │   ├── potion_03.tres
│   │   │   ├── potion_04.tres
│   │   │   ├── potion_05.tres
│   │   │   ├── potion_06.tres
│   │   │   ├── potion_07.tres
│   │   │   ├── potion_08.tres
│   │   │   ├── potion_09.tres
│   │   │   ├── potion_10.tres
│   │   │   ├── potion_blue_01.tres
│   │   │   ├── potion_blue_02.tres
│   │   │   ├── potion_blue_03.tres
│   │   │   ├── potion_blue_04.tres
│   │   │   ├── potion_blue_05.tres
│   │   │   ├── potion_cyan_01.tres
│   │   │   ├── potion_cyan_02.tres
│   │   │   ├── potion_cyan_03.tres
│   │   │   ├── potion_green_01.tres
│   │   │   ├── potion_green_02.tres
│   │   │   ├── potion_green_03.tres
│   │   │   ├── potion_heart_01.tres
│   │   │   ├── potion_heart_02.tres
│   │   │   ├── potion_orange_01.tres
│   │   │   ├── potion_orange_02.tres
│   │   │   ├── potion_orange_03.tres
│   │   │   ├── potion_purple_01.tres
│   │   │   ├── potion_purple_02.tres
│   │   │   ├── potion_purple_03.tres
│   │   │   ├── potion_red_01.tres
│   │   │   ├── potion_red_02.tres
│   │   │   ├── potion_red_03.tres
│   │   │   ├── potion_yellow_01.tres
│   │   │   └── potion_yellow_02.tres
│   │   ├── rings/
│   │   │   ├── ring_01.tres
│   │   │   ├── ring_02.tres
│   │   │   ├── ring_03.tres
│   │   │   ├── ring_04.tres
│   │   │   ├── ring_05.tres
│   │   │   ├── ring_06.tres
│   │   │   ├── ring_07.tres
│   │   │   └── ring_08.tres
│   │   ├── rockets/
│   │   │   ├── rocket_01.tres
│   │   │   ├── rocket_02.tres
│   │   │   ├── rocket_03.tres
│   │   │   ├── rocket_04.tres
│   │   │   ├── rocket_05.tres
│   │   │   ├── rocket_06.tres
│   │   │   └── rocket_07.tres
│   │   ├── scrolls/
│   │   │   ├── scroll_01.tres
│   │   │   ├── scroll_02.tres
│   │   │   ├── scroll_03.tres
│   │   │   ├── scroll_04.tres
│   │   │   ├── scroll_05.tres
│   │   │   ├── scroll_06.tres
│   │   │   ├── scroll_07.tres
│   │   │   └── scroll_08.tres
│   │   ├── shields/
│   │   │   ├── shield_bronze.tres
│   │   │   ├── shield_castle.tres
│   │   │   ├── shield_gray_with_gold_emblem.tres
│   │   │   ├── shield_green.tres
│   │   │   ├── shield_skull.tres
│   │   │   ├── shield_white.tres
│   │   │   ├── shield_with_emblem.tres
│   │   │   ├── shield_with_gold_helmet.tres
│   │   │   ├── shield_wood.tres
│   │   │   ├── shield_wood_small.tres
│   │   │   └── shield_wood_small_glowing.tres
│   │   ├── spears/
│   │   │   ├── many_spears_01.tres
│   │   │   ├── many_spears_02.tres
│   │   │   ├── spear_01.tres
│   │   │   ├── spear_02.tres
│   │   │   └── spear_03.tres
│   │   ├── statues/
│   │   │   ├── statue_01.tres
│   │   │   ├── statue_02.tres
│   │   │   ├── statue_03.tres
│   │   │   ├── statue_dwarf_01.tres
│   │   │   ├── statue_dwarf_02.tres
│   │   │   └── statue_warrior.tres
│   │   ├── staves/
│   │   │   ├── staff_01.tres
│   │   │   ├── staff_02.tres
│   │   │   ├── staff_03.tres
│   │   │   ├── staff_04.tres
│   │   │   ├── staff_05.tres
│   │   │   ├── staff_06.tres
│   │   │   ├── staff_07.tres
│   │   │   ├── wand_01.tres
│   │   │   ├── wand_02.tres
│   │   │   ├── wand_03.tres
│   │   │   ├── wand_04.tres
│   │   │   ├── wand_05.tres
│   │   │   └── wand_glowing.tres
│   │   ├── swords/
│   │   │   ├── greatsword_01.tres
│   │   │   ├── greatsword_02.tres
│   │   │   ├── greatsword_03.tres
│   │   │   ├── greatsword_04.tres
│   │   │   ├── greatsword_05.tres
│   │   │   ├── sword_01.tres
│   │   │   ├── sword_02.tres
│   │   │   ├── sword_03.tres
│   │   │   ├── sword_swing_01.tres
│   │   │   └── sword_swing_02.tres
│   │   ├── tier_icons/
│   │   │   ├── common_1.tres
│   │   │   ├── common_2.tres
│   │   │   ├── common_3.tres
│   │   │   ├── common_4.tres
│   │   │   ├── common_5.tres
│   │   │   ├── common_6.tres
│   │   │   ├── common_7.tres
│   │   │   ├── rare_1.tres
│   │   │   ├── rare_2.tres
│   │   │   ├── rare_3.tres
│   │   │   ├── rare_4.tres
│   │   │   ├── rare_5.tres
│   │   │   ├── rare_6.tres
│   │   │   ├── rare_7.tres
│   │   │   ├── uncommon_1.tres
│   │   │   ├── uncommon_2.tres
│   │   │   ├── uncommon_3.tres
│   │   │   ├── uncommon_4.tres
│   │   │   ├── uncommon_5.tres
│   │   │   ├── uncommon_6.tres
│   │   │   ├── uncommon_7.tres
│   │   │   ├── unique_1.tres
│   │   │   ├── unique_2.tres
│   │   │   ├── unique_3.tres
│   │   │   ├── unique_4.tres
│   │   │   ├── unique_5.tres
│   │   │   ├── unique_6.tres
│   │   │   └── unique_7.tres
│   │   ├── tower_icons/
│   │   │   ├── abandoned_pit.tres
│   │   │   ├── abominable_snowman.tres
│   │   │   ├── afflicted_obelisk.tres
│   │   │   ├── ancient_energy_converter.tres
│   │   │   ├── annoyed_tree.tres
│   │   │   ├── arcane_storm.tres
│   │   │   ├── area_roaster.tres
│   │   │   ├── ash_geyser.tres
│   │   │   ├── astral_lantern.tres
│   │   │   ├── astral_rift.tres
│   │   │   ├── baby_plant.tres
│   │   │   ├── baby_tuskin.tres
│   │   │   ├── ball_lightning_accelerator.tres
│   │   │   ├── basic_knowledge.tres
│   │   │   ├── black_dragon_roost.tres
│   │   │   ├── black_rock_totem.tres
│   │   │   ├── bomb_turret.tres
│   │   │   ├── bone_shrine.tres
│   │   │   ├── bonk_the_living_mountain.tres
│   │   │   ├── broken_cage.tres
│   │   │   ├── broken_circle_of_wind.tres
│   │   │   ├── broken_fire_pit.tres
│   │   │   ├── broken_lightning_rod.tres
│   │   │   ├── bronze_dragon_roost.tres
│   │   │   ├── buried_soul.tres
│   │   │   ├── burning_watchtower.tres
│   │   │   ├── burrow.tres
│   │   │   ├── caged_fire.tres
│   │   │   ├── cenarion.tres
│   │   │   ├── chaining_storm.tres
│   │   │   ├── chaos_warlock.tres
│   │   │   ├── charged_obelisk.tres
│   │   │   ├── chilled_spire.tres
│   │   │   ├── cloud_warrior.tres
│   │   │   ├── cloudy_temple_of_absorption.tres
│   │   │   ├── coconut_sapling.tres
│   │   │   ├── coin_machine.tres
│   │   │   ├── cold_obelisk.tres
│   │   │   ├── cold_troll.tres
│   │   │   ├── contraption.tres
│   │   │   ├── crimson_wyrm.tres
│   │   │   ├── cruel_fire.tres
│   │   │   ├── cursed_grounds.tres
│   │   │   ├── cute_small_spider.tres
│   │   │   ├── dark_battery.tres
│   │   │   ├── dark_fire_pit.tres
│   │   │   ├── death_knight.tres
│   │   │   ├── dimensional_flux_collector.tres
│   │   │   ├── dragon_sorcerer.tres
│   │   │   ├── drake_whisperer.tres
│   │   │   ├── dreadlord.tres
│   │   │   ├── dutchmans_grave.tres
│   │   │   ├── dwarven_forgery.tres
│   │   │   ├── ebonfrost_crystal.tres
│   │   │   ├── embershell_turtle_hatchling.tres
│   │   │   ├── energy_junction.tres
│   │   │   ├── essence_of_fury.tres
│   │   │   ├── felweed.tres
│   │   │   ├── fenced_flames.tres
│   │   │   ├── fiery_dog.tres
│   │   │   ├── fiery_pebble.tres
│   │   │   ├── fire_battery.tres
│   │   │   ├── fire_star.tres
│   │   │   ├── firestorm_cell.tres
│   │   │   ├── fisherman.tres
│   │   │   ├── forest_archer.tres
│   │   │   ├── forest_protectress.tres
│   │   │   ├── forest_troll.tres
│   │   │   ├── frost_root.tres
│   │   │   ├── frosty_rock.tres
│   │   │   ├── frozen_well.tres
│   │   │   ├── garden_of_eden.tres
│   │   │   ├── gatling_gun.tres
│   │   │   ├── genis_sage.tres
│   │   │   ├── geothermal_extractor.tres
│   │   │   ├── glaive_master.tres
│   │   │   ├── glowing_solar_orb.tres
│   │   │   ├── gnoll_thunder_mage.tres
│   │   │   ├── goblin_stronghold.tres
│   │   │   ├── grab-o-bot.tres
│   │   │   ├── green_dragon_roost.tres
│   │   │   ├── green_lightning.tres
│   │   │   ├── greyfang.tres
│   │   │   ├── gryphon_rider.tres
│   │   │   ├── hall_of_souls.tres
│   │   │   ├── harby.tres
│   │   │   ├── harpy_witch.tres
│   │   │   ├── haunted_rubble.tres
│   │   │   ├── healing_obelisk.tres
│   │   │   ├── helicopter_zone.tres
│   │   │   ├── hell_bat.tres
│   │   │   ├── holy_energy.tres
│   │   │   ├── ice_battery.tres
│   │   │   ├── icy_core.tres
│   │   │   ├── icy_skulls.tres
│   │   │   ├── icy_spirit.tres
│   │   │   ├── igloo.tres
│   │   │   ├── inexperienced_huntress.tres
│   │   │   ├── inflamed_stone.tres
│   │   │   ├── initiate_elementalist.tres
│   │   │   ├── it.tres
│   │   │   ├── jungle_stalker.tres
│   │   │   ├── kraken.tres
│   │   │   ├── lesser_astral_defender.tres
│   │   │   ├── lesser_dark_defender.tres
│   │   │   ├── lesser_elemental_ghost.tres
│   │   │   ├── lesser_flamy_defender.tres
│   │   │   ├── lesser_ice_defender.tres
│   │   │   ├── lesser_iron_defender.tres
│   │   │   ├── lesser_natural_defender.tres
│   │   │   ├── lesser_priest.tres
│   │   │   ├── lesser_skeletal_mage.tres
│   │   │   ├── lesser_storm_defender.tres
│   │   │   ├── lesser_wolves_den.tres
│   │   │   ├── library_of_alexandria.tres
│   │   │   ├── lich_king.tres
│   │   │   ├── lightning_eye.tres
│   │   │   ├── lightning_generator.tres
│   │   │   ├── lightning_totem.tres
│   │   │   ├── little_phoenix.tres
│   │   │   ├── living_volcano.tres
│   │   │   ├── lunar_emitter.tres
│   │   │   ├── lunar_sentinel.tres
│   │   │   ├── magic_battery.tres
│   │   │   ├── magic_mushroom.tres
│   │   │   ├── magna_warrior.tres
│   │   │   ├── mana-touched_drake.tres
│   │   │   ├── marine.tres
│   │   │   ├── meteor_totem.tres
│   │   │   ├── militia_watchtower.tres
│   │   │   ├── miner.tres
│   │   │   ├── minor_magic_ruin.tres
│   │   │   ├── mister_fireflies.tres
│   │   │   ├── monolith_of_chaos.tres
│   │   │   ├── morphling.tres
│   │   │   ├── mossy_acid_sprayer.tres
│   │   │   ├── mud_golem.tres
│   │   │   ├── nature_sprites.tres
│   │   │   ├── necromantic_altar.tres
│   │   │   ├── nortrom_the_silencer.tres
│   │   │   ├── nuclear_missile_launcher.tres
│   │   │   ├── obelisk_of_fortuity.tres
│   │   │   ├── owl_of_wisdom.tres
│   │   │   ├── particle_accelerator.tres
│   │   │   ├── phantom.tres
│   │   │   ├── plagued_crypt.tres
│   │   │   ├── planar_gate.tres
│   │   │   ├── poison_battery.tres
│   │   │   ├── polar_bear_cub.tres
│   │   │   ├── portal_to_swine_purgatory.tres
│   │   │   ├── prince_of_lightning.tres
│   │   │   ├── princess_of_light.tres
│   │   │   ├── razorboar_thornweaver.tres
│   │   │   ├── red_ball_lightning.tres
│   │   │   ├── regenerating_well.tres
│   │   │   ├── rooted_chasm.tres
│   │   │   ├── rotted_flashing_grave.tres
│   │   │   ├── rowing_boat.tres
│   │   │   ├── ruined_monolith.tres
│   │   │   ├── ruined_storm_cap.tres
│   │   │   ├── ruined_sun_pedestal.tres
│   │   │   ├── ruined_wind_tower.tres
│   │   │   ├── rundown_iron_sentry.tres
│   │   │   ├── sacred_altar.tres
│   │   │   ├── sacrificial_lamb.tres
│   │   │   ├── safirons_cold_grave.tres
│   │   │   ├── scales.tres
│   │   │   ├── sea_turtle.tres
│   │   │   ├── servant_of_the_twin_flames.tres
│   │   │   ├── sewer_connection.tres
│   │   │   ├── shadow.tres
│   │   │   ├── shaman.tres
│   │   │   ├── shard_of_souls.tres
│   │   │   ├── silver_knight.tres
│   │   │   ├── skink.tres
│   │   │   ├── small_brazier.tres
│   │   │   ├── small_bug_nest.tres
│   │   │   ├── small_cactus.tres
│   │   │   ├── small_fire_sprayer.tres
│   │   │   ├── small_frost_fire.tres
│   │   │   ├── small_frozen_mushroom.tres
│   │   │   ├── small_ice_mine.tres
│   │   │   ├── small_light.tres
│   │   │   ├── small_pocket_rocket.tres
│   │   │   ├── small_ray_blaster.tres
│   │   │   ├── small_serpent_ward.tres
│   │   │   ├── small_torch.tres
│   │   │   ├── sniper.tres
│   │   │   ├── snowy_pebble.tres
│   │   │   ├── solar_collector.tres
│   │   │   ├── solar_emitter.tres
│   │   │   ├── sorceress.tres
│   │   │   ├── soul_vault.tres
│   │   │   ├── soulflame_device.tres
│   │   │   ├── spell_collector.tres
│   │   │   ├── spider_queen.tres
│   │   │   ├── star_gazer.tres
│   │   │   ├── storm_battery.tres
│   │   │   ├── storm_coil.tres
│   │   │   ├── storm_focus.tres
│   │   │   ├── stormy_dog.tres
│   │   │   ├── sun_crusader.tres
│   │   │   ├── taita_the_hermit.tres
│   │   │   ├── teacher.tres
│   │   │   ├── tentacle_spawn.tres
│   │   │   ├── the_conduit.tres
│   │   │   ├── the_council_of_demons.tres
│   │   │   ├── the_fire_lord.tres
│   │   │   ├── the_frozen_wyrm.tres
│   │   │   ├── the_furnace.tres
│   │   │   ├── the_omnislasher.tres
│   │   │   ├── the_steam_engine.tres
│   │   │   ├── thief_apprentice.tres
│   │   │   ├── tidewater_stream.tres
│   │   │   ├── time_manipulator.tres
│   │   │   ├── timevault.tres
│   │   │   ├── tiny_shrub.tres
│   │   │   ├── tiny_storm_lantern.tres
│   │   │   ├── tombstone.tres
│   │   │   ├── trash_heap.tres
│   │   │   ├── tree_stump.tres
│   │   │   ├── tundra_stalker.tres
│   │   │   ├── undisturbed_crypt.tres
│   │   │   ├── valor.tres
│   │   │   ├── village_witch.tres
│   │   │   ├── void_drake.tres
│   │   │   ├── vulshok_the_berserker.tres
│   │   │   ├── warrior_of_light.tres
│   │   │   ├── wild_warbeast.tres
│   │   │   ├── witch_doctor.tres
│   │   │   ├── wooden_trap.tres
│   │   │   ├── xeno_research_facility.tres
│   │   │   ├── ymir.tres
│   │   │   ├── young_northern_troll.tres
│   │   │   ├── zealot.tres
│   │   │   └── zeus.tres
│   │   ├── tower_variations/
│   │   │   ├── ash_geyser_blue.tres
│   │   │   ├── ash_geyser_green.tres
│   │   │   ├── ash_geyser_purple.tres
│   │   │   ├── bonk_the_living_mountain_small.tres
│   │   │   ├── forest_troll_small.tres
│   │   │   ├── meteor_totem_blue.tres
│   │   │   ├── meteor_totem_purple.tres
│   │   │   ├── mossy_acid_sprayer_gray.tres
│   │   │   ├── mossy_acid_sprayer_red.tres
│   │   │   ├── undisturbed_crypt_gold.tres
│   │   │   └── vulshok_the_berserker_blue.tres
│   │   ├── trinkets/
│   │   │   ├── claw_01.tres
│   │   │   ├── claw_02.tres
│   │   │   ├── claw_03.tres
│   │   │   ├── key_01.tres
│   │   │   ├── key_02.tres
│   │   │   ├── key_03.tres
│   │   │   ├── trinket_01.tres
│   │   │   ├── trinket_02.tres
│   │   │   ├── trinket_03.tres
│   │   │   ├── trinket_04.tres
│   │   │   ├── trinket_05.tres
│   │   │   ├── trinket_06.tres
│   │   │   ├── trinket_07.tres
│   │   │   ├── trinket_08.tres
│   │   │   ├── trinket_09.tres
│   │   │   └── trinket_10.tres
│   │   ├── undead/
│   │   │   ├── demon_emblem.tres
│   │   │   ├── monster_hand.tres
│   │   │   ├── skull_01.tres
│   │   │   ├── skull_02.tres
│   │   │   ├── skull_03.tres
│   │   │   ├── skull_04.tres
│   │   │   ├── skull_05.tres
│   │   │   ├── skull_06.tres
│   │   │   ├── skull_doll.tres
│   │   │   ├── skull_phazing.tres
│   │   │   ├── skull_wand_01.tres
│   │   │   ├── skull_wand_02.tres
│   │   │   ├── skull_wand_03.tres
│   │   │   └── skull_wand_04.tres
│   │   └── weapons_misc/
│   │       ├── axe_01.tres
│   │       ├── axe_02.tres
│   │       ├── barbed_spike.tres
│   │       ├── glaive_01.tres
│   │       ├── glaive_02.tres
│   │       ├── glaive_03.tres
│   │       ├── mining_pick_01.tres
│   │       ├── mining_pick_02.tres
│   │       ├── trident_01.tres
│   │       └── trident_02.tres
│   ├── misc/
│   │   ├── barrel.tres
│   │   └── pulsing_dot.tres
│   ├── shaders/
│   │   ├── foggy_camera.gdshader
│   │   ├── glowing_outline.gdshader
│   │   ├── glowing_outline.material
│   │   ├── glowing_outline_2.gdshader
│   │   └── saturation_burn.gdshader
│   ├── theme/
│   │   ├── common/
│   │   │   ├── rect_container_center_l.tres
│   │   │   ├── rect_container_l.tres
│   │   │   ├── rect_container_m.tres
│   │   │   ├── rect_container_s.tres
│   │   │   └── tab_container_m.tres
│   │   ├── element_towers_info/
│   │   │   └── empty_button_style_box.tres
│   │   ├── health_bar_background.tres
│   │   ├── health_bar_fill.tres
│   │   ├── item_button_hover.tres
│   │   ├── item_button_normal.tres
│   │   ├── item_button_pressed.tres
│   │   ├── mission_complete_indicator.tres
│   │   ├── player_resource_display/
│   │   │   ├── circle_container_l.tres
│   │   │   ├── rect_container_center_l.tres
│   │   │   ├── rect_container_left_l.tres
│   │   │   ├── rect_container_right_l.tres
│   │   │   ├── rect_container_top_menu.tres
│   │   │   ├── resource_status_panel.tres
│   │   │   └── stash_panel_background.tres
│   │   ├── selected_unit_info/
│   │   │   ├── mana_bar_fill.tres
│   │   │   ├── panel_container.tres
│   │   │   └── progress_bar_background.tres
│   │   ├── tower_actions/
│   │   │   ├── button_disabled.tres
│   │   │   ├── button_normal.tres
│   │   │   └── button_pressed.tres
│   │   ├── unit_button/
│   │   │   ├── button_disabled.tres
│   │   │   ├── button_hover.tres
│   │   │   ├── button_normal.tres
│   │   │   ├── common_rarity_panel_container.tres
│   │   │   ├── passive_ability_button.tres
│   │   │   ├── rare_rarity_panel_container.tres
│   │   │   ├── small_button_disabled.tres
│   │   │   ├── small_button_hover.tres
│   │   │   ├── small_button_normal.tres
│   │   │   ├── uncommon_rarity_panel_container.tres
│   │   │   └── unique_rarity_panel_container.tres
│   │   ├── unit_button_container/
│   │   │   └── counter_label_normal.tres
│   │   ├── unit_menu/
│   │   │   ├── button_disalbed.tres
│   │   │   ├── button_hover.tres
│   │   │   ├── button_normal.tres
│   │   │   ├── exp_bar_background.tres
│   │   │   ├── exp_bar_fill.tres
│   │   │   ├── health_bar_background.tres
│   │   │   ├── health_bar_fill.tres
│   │   │   ├── mana_bar_background.tres
│   │   │   ├── mana_bar_fill.tres
│   │   │   ├── title_button_normal.tres
│   │   │   ├── unit_level_label_normal.tres
│   │   │   ├── unit_menu_panel.tres
│   │   │   └── unit_name_label_normal.tres
│   │   └── wc3_theme.tres
│   ├── tilesets/
│   │   ├── buildable_area_tiles.tres
│   │   └── decorations.tres
│   └── ui_textures/
│       ├── buff_group_both.tres
│       ├── buff_group_incoming.tres
│       ├── buff_group_none.tres
│       ├── buff_group_outgoing.tres
│       ├── button_container_hover.tres
│       ├── common_background.tres
│       ├── common_unit_button.tres
│       ├── common_unit_button_hover.tres
│       ├── info_icon.tres
│       ├── menu_option_round_button.tres
│       ├── menu_option_round_button_hover.tres
│       ├── portal_lives_round_bg.tres
│       ├── rare_background.tres
│       ├── rare_unit_button.tres
│       ├── rare_unit_button_hover.tres
│       ├── rect_container_center_l.tres
│       ├── rect_container_l.tres
│       ├── rect_container_left_l.tres
│       ├── rect_container_m.tres
│       ├── rect_container_right_l.tres
│       ├── rect_container_s.tres
│       ├── rect_container_s_hover.tres
│       ├── speed_fast.tres
│       ├── speed_fastest.tres
│       ├── speed_normal.tres
│       ├── stash_panel_background.tres
│       ├── uncommon_background.tres
│       ├── uncommon_unit_button.tres
│       ├── uncommon_unit_button_hover.tres
│       ├── unique_background.tres
│       ├── unique_unit_button.tres
│       ├── unique_unit_button_hover.tres
│       ├── unit_button_disabled.tres
│       └── upgrade_icon.tres
├── src/
│   ├── README.md
│   ├── actions/
│   │   ├── action.gd
│   │   ├── action_autocast.gd
│   │   ├── action_autofill.gd
│   │   ├── action_build_tower.gd
│   │   ├── action_change_buffgroup.gd
│   │   ├── action_chat.gd
│   │   ├── action_consume_item.gd
│   │   ├── action_drop_item.gd
│   │   ├── action_focus_target.gd
│   │   ├── action_idle.gd
│   │   ├── action_move_item.gd
│   │   ├── action_research_element.gd
│   │   ├── action_roll_towers.gd
│   │   ├── action_select_builder.gd
│   │   ├── action_select_unit.gd
│   │   ├── action_select_wisdom_upgrades.gd
│   │   ├── action_sell_tower.gd
│   │   ├── action_sort_item_stash.gd
│   │   ├── action_start_next_wave.gd
│   │   ├── action_swap_items.gd
│   │   ├── action_toggle_autocast.gd
│   │   ├── action_transform_tower.gd
│   │   ├── action_transmute.gd
│   │   └── action_upgrade_tower.gd
│   ├── buffs/
│   │   ├── aura.gd
│   │   ├── aura.tscn
│   │   ├── buff.gd
│   │   ├── buff_range_area.gd
│   │   ├── buff_range_area.tscn
│   │   ├── buff_type.gd
│   │   ├── instances/
│   │   │   ├── cb_silence.gd
│   │   │   └── cb_stun.gd
│   │   ├── modification.gd
│   │   ├── modifier.gd
│   │   └── target_type.gd
│   ├── builders/
│   │   ├── builder.gd
│   │   └── instances/
│   │       ├── builder_adventurer.gd
│   │       ├── builder_antagonizer.gd
│   │       ├── builder_arch_sorceress.gd
│   │       ├── builder_backpacker.gd
│   │       ├── builder_barbarian_warlord.gd
│   │       ├── builder_benevolent_witch.gd
│   │       ├── builder_blademaster.gd
│   │       ├── builder_elementalist.gd
│   │       ├── builder_farseer.gd
│   │       ├── builder_feeble_fender.gd
│   │       ├── builder_goblin_alchemist.gd
│   │       ├── builder_iron_maiden.gd
│   │       ├── builder_master_of_encyclopedic_wisdom.gd
│   │       ├── builder_maverick.gd
│   │       ├── builder_naga_time_twister.gd
│   │       ├── builder_none.gd
│   │       ├── builder_panda_monk.gd
│   │       ├── builder_queen.gd
│   │       ├── builder_realist.gd
│   │       ├── builder_royal_assassin.gd
│   │       ├── builder_spirit_warden.gd
│   │       └── builder_veteran_pilot.gd
│   ├── creeps/
│   │   ├── creep.gd
│   │   ├── creep_blood_pool.gd
│   │   ├── creep_blood_pool.tscn
│   │   ├── creep_corpse.gd
│   │   ├── creep_corpse.tscn
│   │   ├── creep_spawner.gd
│   │   ├── creep_spawner.tscn
│   │   ├── creep_sprite.gd
│   │   ├── health_bar.gd
│   │   ├── instances/
│   │   │   ├── challenge/
│   │   │   │   ├── challenge_boss_creep.tscn
│   │   │   │   └── challenge_mass_creep.tscn
│   │   │   ├── creep.tscn
│   │   │   └── orc/
│   │   │       ├── orc_air_creep.tscn
│   │   │       ├── orc_boss_creep.tscn
│   │   │       ├── orc_champion_creep.tscn
│   │   │       ├── orc_mass_creep.tscn
│   │   │       └── orc_normal_creep.tscn
│   │   ├── packed_metadata.gd
│   │   ├── special_buffs/
│   │   │   ├── creep_armored.gd
│   │   │   ├── creep_broody.gd
│   │   │   ├── creep_dart.gd
│   │   │   ├── creep_ethereal.gd
│   │   │   ├── creep_evasion.gd
│   │   │   ├── creep_evolving.gd
│   │   │   ├── creep_fireball.gd
│   │   │   ├── creep_flock.gd
│   │   │   ├── creep_ghost.gd
│   │   │   ├── creep_gravid.gd
│   │   │   ├── creep_greater_speed.gd
│   │   │   ├── creep_greater_spell_resistance.gd
│   │   │   ├── creep_heavy_armored.gd
│   │   │   ├── creep_invisible.gd
│   │   │   ├── creep_magic_immunity.gd
│   │   │   ├── creep_mana_drain_aura.gd
│   │   │   ├── creep_manashield+.gd
│   │   │   ├── creep_manashield.gd
│   │   │   ├── creep_meaty.gd
│   │   │   ├── creep_mechanical.gd
│   │   │   ├── creep_necromancer.gd
│   │   │   ├── creep_protector.gd
│   │   │   ├── creep_purge_revenge.gd
│   │   │   ├── creep_regeneration.gd
│   │   │   ├── creep_relic_raider.gd
│   │   │   ├── creep_rich.gd
│   │   │   ├── creep_second_chance.gd
│   │   │   ├── creep_semi-mechanical.gd
│   │   │   ├── creep_slow.gd
│   │   │   ├── creep_slow_aura.gd
│   │   │   ├── creep_speed.gd
│   │   │   ├── creep_spell_resistance.gd
│   │   │   ├── creep_spellbinder.gd
│   │   │   ├── creep_strong.gd
│   │   │   ├── creep_stun_revenge.gd
│   │   │   ├── creep_ultra_wisdom.gd
│   │   │   ├── creep_unlucky.gd
│   │   │   ├── creep_xtreme_armor.gd
│   │   │   ├── creep_xtreme_evasion.gd
│   │   │   ├── creep_xtreme_regeneration.gd
│   │   │   └── creep_xtreme_speed.gd
│   │   ├── special_icons/
│   │   │   ├── CreepArmoredSpecial.tscn
│   │   │   ├── CreepBroodySpecial.tscn
│   │   │   ├── CreepDartSpecial.tscn
│   │   │   ├── CreepEtherealSpecial.tscn
│   │   │   ├── CreepEvasionSpecial.tscn
│   │   │   ├── CreepEvolvingSpecial.tscn
│   │   │   ├── CreepFireballSpecial.tscn
│   │   │   ├── CreepFlockSpecial.tscn
│   │   │   ├── CreepGhostSpecial.tscn
│   │   │   ├── CreepGravidSpecial.tscn
│   │   │   ├── CreepGreaterSpeedSpecial.tscn
│   │   │   ├── CreepGreaterSpellResistanceSpecial.tscn
│   │   │   ├── CreepHeavyArmoredSpecial.tscn
│   │   │   ├── CreepInvisibleSpecial.tscn
│   │   │   ├── CreepMagicImmunitySpecial.tscn
│   │   │   ├── CreepManaDrainAuraSpecial.tscn
│   │   │   ├── CreepManaShieldPlusSpecial.tscn
│   │   │   ├── CreepManaShieldSpecial.tscn
│   │   │   ├── CreepMeatySpecial.tscn
│   │   │   ├── CreepMechanicalSpecial.tscn
│   │   │   ├── CreepNecromancerSpecial.tscn
│   │   │   ├── CreepProtectorSpecial.tscn
│   │   │   ├── CreepPurgeRevengeSpecial.tscn
│   │   │   ├── CreepRegenerationSpecial.tscn
│   │   │   ├── CreepRelicRaiderSpecial.tscn
│   │   │   ├── CreepRichSpecial.tscn
│   │   │   ├── CreepSecondChanceSpecial.tscn
│   │   │   ├── CreepSemiMechanicalSpecial.tscn
│   │   │   ├── CreepSlowAuraSpecial.tscn
│   │   │   ├── CreepSlowSpecial.tscn
│   │   │   ├── CreepSpeedSpecial.tscn
│   │   │   ├── CreepSpellResistanceSpecial.tscn
│   │   │   ├── CreepSpellbinderSpecial.tscn
│   │   │   ├── CreepStrongSpecial.tscn
│   │   │   ├── CreepStunRevengeSpecial.tscn
│   │   │   ├── CreepUltraWisdomSpecial.tscn
│   │   │   ├── CreepUnluckySpecial.tscn
│   │   │   ├── CreepXtremeArmorSpecial.tscn
│   │   │   ├── CreepXtremeEvasionSpecial.tscn
│   │   │   ├── CreepXtremeRegenerationSpecial.tscn
│   │   │   └── CreepXtremeSpeedSpecial.tscn
│   │   ├── wave.gd
│   │   ├── wave_path.gd
│   │   ├── wave_spawner.gd
│   │   └── wave_spawner.tscn
│   ├── effects/
│   │   ├── ancient_protector_missile.tscn
│   │   ├── animated_dead_target.tscn
│   │   ├── apply_potion.tscn
│   │   ├── arcane_tower_attack.tscn
│   │   ├── arcane_tower_attack_flat.tscn
│   │   ├── avatar_caster.tscn
│   │   ├── banshee_missile.tscn
│   │   ├── barrel.tscn
│   │   ├── blink_target.tscn
│   │   ├── blood_splatter.tscn
│   │   ├── build_tower.tscn
│   │   ├── charm_target.tscn
│   │   ├── chimaera_acid.tscn
│   │   ├── cloud_of_fog_cycle.tscn
│   │   ├── cloud_of_fog_small.tscn
│   │   ├── cripple_target.tscn
│   │   ├── crushing_wave.tscn
│   │   ├── crypt_fiend_eggsack.tscn
│   │   ├── cyclone_target.tscn
│   │   ├── death_and_decay.tscn
│   │   ├── death_coil.tscn
│   │   ├── death_explode.tscn
│   │   ├── devour.tscn
│   │   ├── dispel_magic_target.tscn
│   │   ├── doom_death.tscn
│   │   ├── effects_container.gd
│   │   ├── faerie_dragon_missile.tscn
│   │   ├── firelord_death_explode.tscn
│   │   ├── flame_strike_embers.tscn
│   │   ├── flower_aura.tscn
│   │   ├── frag_boom_spawn.tscn
│   │   ├── freezing_breath.tscn
│   │   ├── freezing_breath_purple.tscn
│   │   ├── frost_armor_damage.tscn
│   │   ├── frost_armor_damage_purple.tscn
│   │   ├── frost_bolt_missile.tscn
│   │   ├── glaive.tscn
│   │   ├── gold_credit.tscn
│   │   ├── healing_wave_target.tscn
│   │   ├── holy_bolt.tscn
│   │   ├── holy_bolt_green.tscn
│   │   ├── howl_caster.tscn
│   │   ├── immolation_damage.tscn
│   │   ├── impale_hit_target.tscn
│   │   ├── impale_target_dust.tscn
│   │   ├── incinerate.tscn
│   │   ├── interpolated_sprite.gd
│   │   ├── keeper_grove_missile.tscn
│   │   ├── level_up.tscn
│   │   ├── mana_burn_target.tscn
│   │   ├── mana_shield_cycle.tscn
│   │   ├── mass_teleport_caster.tscn
│   │   ├── mass_teleport_target.tscn
│   │   ├── monsoon_bolt.tscn
│   │   ├── moonwell_target.tscn
│   │   ├── mortar_missile.tscn
│   │   ├── naga_death.tscn
│   │   ├── ne_cancel_death.tscn
│   │   ├── ne_death.tscn
│   │   ├── placeholder.tscn
│   │   ├── polymorph_target.tscn
│   │   ├── projectile_explosion_astral.tscn
│   │   ├── projectile_explosion_darkness.tscn
│   │   ├── projectile_explosion_fire.tscn
│   │   ├── projectile_explosion_ice.tscn
│   │   ├── projectile_explosion_iron.tscn
│   │   ├── projectile_explosion_nature.tscn
│   │   ├── projectile_explosion_storm.tscn
│   │   ├── purge_buff_target.tscn
│   │   ├── quillspray.tscn
│   │   ├── raise_skeleton.tscn
│   │   ├── replenish_mana.tscn
│   │   ├── revive_human.tscn
│   │   ├── roar.tscn
│   │   ├── roots.tscn
│   │   ├── shackle.tscn
│   │   ├── shockwave_missile.tscn
│   │   ├── silence_area.tscn
│   │   ├── small_flame_spawn.tscn
│   │   ├── spell_aiil.tscn
│   │   ├── spell_ailb.tscn
│   │   ├── spell_aima.tscn
│   │   ├── spell_aire.tscn
│   │   ├── spell_aire_flat.tscn
│   │   ├── spell_aiso.tscn
│   │   ├── spell_alim.tscn
│   │   ├── spell_breaker_target.tscn
│   │   ├── spirit_link_target.tscn
│   │   ├── stampede_missile_death.tscn
│   │   ├── starfall_target.tscn
│   │   ├── stun_visual.tscn
│   │   ├── target_arrow.gd
│   │   ├── target_arrow.tscn
│   │   ├── thunder_clap.tscn
│   │   ├── undead_dissipate.tscn
│   │   ├── upgrade_tower.tscn
│   │   ├── vampiric_aura.tscn
│   │   ├── voodoo_aura.tscn
│   │   ├── warstomp_caster.tscn
│   │   ├── wind_shear.tscn
│   │   ├── wisp_explode.tscn
│   │   ├── witch_doctor_ward.tscn
│   │   ├── ziggurat_frost_missile.tscn
│   │   └── zombify_target.tscn
│   ├── enums/
│   │   ├── README.md
│   │   ├── armor_type.gd
│   │   ├── attack_type.gd
│   │   ├── buff_group_mode.gd
│   │   ├── builder_tier.gd
│   │   ├── creep_category.gd
│   │   ├── creep_size.gd
│   │   ├── difficulty.gd
│   │   ├── display_mode.gd
│   │   ├── element.gd
│   │   ├── game_mode.gd
│   │   ├── item_type.gd
│   │   ├── language.gd
│   │   ├── modification_type.gd
│   │   ├── player_mode.gd
│   │   ├── rarity.gd
│   │   └── team_mode.gd
│   ├── game_scene/
│   │   ├── build_space.gd
│   │   ├── build_tower.gd
│   │   ├── camera_controller.gd
│   │   ├── chat_commands.gd
│   │   ├── combat_log_storage.gd
│   │   ├── game_client.gd
│   │   ├── game_client.tscn
│   │   ├── game_host.gd
│   │   ├── game_host.tscn
│   │   ├── game_scene.gd
│   │   ├── game_scene.tscn
│   │   ├── game_time.gd
│   │   ├── horadric_cube.gd
│   │   ├── manual_timer.gd
│   │   ├── mouse_state.gd
│   │   ├── move_item.gd
│   │   ├── select_point_for_cast.gd
│   │   ├── select_target_for_cast.gd
│   │   ├── select_unit.gd
│   │   ├── team_container.gd
│   │   └── tutorial_controller.gd
│   ├── items/
│   │   ├── README.md
│   │   ├── item.gd
│   │   ├── item_behavior.gd
│   │   ├── item_behaviors/
│   │   │   ├── aqueous_vapor.gd
│   │   │   ├── arcane_book_of_power.gd
│   │   │   ├── arcane_oil_of_lore.gd
│   │   │   ├── arcane_script.gd
│   │   │   ├── arms_dealer.gd
│   │   │   ├── artifact_of_skadi.gd
│   │   │   ├── backpack.gd
│   │   │   ├── ball_lightning.gd
│   │   │   ├── bartucs_spirit.gd
│   │   │   ├── basics_of_calculus.gd
│   │   │   ├── bhaals_essence.gd
│   │   │   ├── blaster_staff.gd
│   │   │   ├── bloodthirsty_wheel_of_fortune.gd
│   │   │   ├── bloody_key.gd
│   │   │   ├── bones_of_essence.gd
│   │   │   ├── bonks_face.gd
│   │   │   ├── book_of_force.gd
│   │   │   ├── book_of_knowledge.gd
│   │   │   ├── brimstone_helmet.gd
│   │   │   ├── chameleon_glaive.gd
│   │   │   ├── chameleons_soul.gd
│   │   │   ├── charged_disk.gd
│   │   │   ├── chrono_jumper.gd
│   │   │   ├── circle_of_power.gd
│   │   │   ├── commander.gd
│   │   │   ├── consumable_chicken.gd
│   │   │   ├── consumable_hobbit.gd
│   │   │   ├── consumable_piggy.gd
│   │   │   ├── consumable_plant.gd
│   │   │   ├── crescent_stone.gd
│   │   │   ├── crit_blade.gd
│   │   │   ├── cruel_torch.gd
│   │   │   ├── currency_converter.gd
│   │   │   ├── cursed_claw.gd
│   │   │   ├── dagger_of_bane.gd
│   │   │   ├── dark_matter_trident.gd
│   │   │   ├── deep_shadows.gd
│   │   │   ├── distorted_idol.gd
│   │   │   ├── divine_book_of_omnipotence.gd
│   │   │   ├── dooms_ensign.gd
│   │   │   ├── elunes_bow.gd
│   │   │   ├── empty_item_behavior.gd
│   │   │   ├── enchanted_knives.gd
│   │   │   ├── essence_of_rot.gd
│   │   │   ├── even_more_magical_hammer.gd
│   │   │   ├── excalibur.gd
│   │   │   ├── eye_of_true_sight.gd
│   │   │   ├── faithful_staff.gd
│   │   │   ├── fist_of_doom.gd
│   │   │   ├── flag_of_the_allegiance.gd
│   │   │   ├── forcefield_generator.gd
│   │   │   ├── fragmentation_round.gd
│   │   │   ├── frog_pipe.gd
│   │   │   ├── glaive_of_supreme_follow_up.gd
│   │   │   ├── golden_decoration.gd
│   │   │   ├── golden_trident.gd
│   │   │   ├── granite_hammer.gd
│   │   │   ├── grounding_gloves.gd
│   │   │   ├── haunted_hand.gd
│   │   │   ├── helm_of_insanity.gd
│   │   │   ├── hippogryph_egg.gd
│   │   │   ├── holy_hand_grenade.gd
│   │   │   ├── item_template_advanced.gd
│   │   │   ├── jah_rakals_fury.gd
│   │   │   ├── jewels_of_the_moon.gd
│   │   │   ├── jungle_stalkers_doll.gd
│   │   │   ├── libram_of_grace.gd
│   │   │   ├── lich_mask.gd
│   │   │   ├── liquid_gold.gd
│   │   │   ├── lucky_gem.gd
│   │   │   ├── lunar_essence.gd
│   │   │   ├── magic_conductor.gd
│   │   │   ├── magic_gloves.gd
│   │   │   ├── magic_hammer.gd
│   │   │   ├── magic_link.gd
│   │   │   ├── magnetic_field.gd
│   │   │   ├── mana_stone.gd
│   │   │   ├── medallion_of_opulence.gd
│   │   │   ├── mefis_rocket.gd
│   │   │   ├── mighty_trees_acorns.gd
│   │   │   ├── mindleecher.gd
│   │   │   ├── mine_cart.gd
│   │   │   ├── mini_forest_troll.gd
│   │   │   ├── mining_tools.gd
│   │   │   ├── mystical_shell.gd
│   │   │   ├── nerminds_eye.gd
│   │   │   ├── never-ending_keg.gd
│   │   │   ├── oil_of_lore.gd
│   │   │   ├── old_hunter.gd
│   │   │   ├── optimists_preserved_face.gd
│   │   │   ├── orb_of_souls.gd
│   │   │   ├── overcharge_shot.gd
│   │   │   ├── pendant_of_mana_supremacy.gd
│   │   │   ├── pendant_of_promptness.gd
│   │   │   ├── phase_gloves.gd
│   │   │   ├── plain_staff.gd
│   │   │   ├── pocket_emporium.gd
│   │   │   ├── polarisator.gd
│   │   │   ├── portable_tombstone.gd
│   │   │   ├── priest_figurine.gd
│   │   │   ├── purifying_gloves.gd
│   │   │   ├── ritual_talisman.gd
│   │   │   ├── scroll_of_piercing_magic.gd
│   │   │   ├── scroll_of_speed.gd
│   │   │   ├── scroll_of_strength.gd
│   │   │   ├── seekers_arcane_oil.gd
│   │   │   ├── seekers_oil.gd
│   │   │   ├── share_knowledge.gd
│   │   │   ├── shining_rock.gd
│   │   │   ├── shrapnel_ammunition.gd
│   │   │   ├── sign_of_energy_infusion.gd
│   │   │   ├── silver_armor.gd
│   │   │   ├── sleeve_of_rage.gd
│   │   │   ├── soul_collectors_cloak.gd
│   │   │   ├── soul_collectors_scythe.gd
│   │   │   ├── soul_extractor.gd
│   │   │   ├── spear_of_loki.gd
│   │   │   ├── speed_demons_reward.gd
│   │   │   ├── spellbook_of_item_mastery.gd
│   │   │   ├── spider_broach.gd
│   │   │   ├── spiderling.gd
│   │   │   ├── staff_of_essence.gd
│   │   │   ├── staff_of_the_wild_equus.gd
│   │   │   ├── stasis_trap.gd
│   │   │   ├── strange_item.gd
│   │   │   ├── stunner.gd
│   │   │   ├── sword_of_decay.gd
│   │   │   ├── sword_of_reckoning.gd
│   │   │   ├── the_divine_wings_of_tragedy.gd
│   │   │   ├── toy_boy.gd
│   │   │   ├── unstable_current.gd
│   │   │   ├── unyielding_maul.gd
│   │   │   ├── vampiric_skull.gd
│   │   │   ├── wand_of_mana_zap.gd
│   │   │   ├── wanted_list.gd
│   │   │   ├── war_drum.gd
│   │   │   ├── wise_mans_cooking_recipe.gd
│   │   │   ├── wizards_soul.gd
│   │   │   ├── wooden_leg.gd
│   │   │   ├── workbench.gd
│   │   │   └── writers_knowledge.gd
│   │   ├── item_container.gd
│   │   ├── item_drop.gd
│   │   ├── item_drop.tscn
│   │   └── tower_item_container.gd
│   ├── map/
│   │   ├── buildable_area.gd
│   │   ├── buildable_area.tscn
│   │   ├── map.gd
│   │   ├── map_big.tscn
│   │   └── map_small.tscn
│   ├── missions/
│   │   ├── instances/
│   │   │   ├── mission_120_in_60min.gd
│   │   │   ├── mission_240_in_120min.gd
│   │   │   ├── mission_35_food_or_less.gd
│   │   │   ├── mission_empty.gd
│   │   │   ├── mission_no_items.gd
│   │   │   ├── mission_no_oils.gd
│   │   │   ├── mission_only_astral_towers.gd
│   │   │   ├── mission_only_common_uncommon.gd
│   │   │   ├── mission_only_darkness_towers.gd
│   │   │   ├── mission_only_fire_towers.gd
│   │   │   ├── mission_only_ice_towers.gd
│   │   │   ├── mission_only_iron_towers.gd
│   │   │   ├── mission_only_nature_towers.gd
│   │   │   └── mission_only_storm_towers.gd
│   │   ├── mission.gd
│   │   ├── mission_manager.gd
│   │   └── mission_manager.tscn
│   ├── player/
│   │   ├── auto_oil.gd
│   │   ├── camera_origin.gd
│   │   ├── camera_origin.tscn
│   │   ├── player.gd
│   │   ├── player.tscn
│   │   ├── team.gd
│   │   ├── team.tscn
│   │   └── tower_stash.gd
│   ├── projectiles/
│   │   ├── projectile.gd
│   │   ├── projectile.tscn
│   │   ├── projectile_type.gd
│   │   └── projectile_visuals/
│   │       ├── ball_lightning_projectile.tscn
│   │       ├── default_projectile.gd
│   │       ├── default_projectile.tscn
│   │       ├── energy_ball.tscn
│   │       ├── flying_pork.tscn
│   │       ├── omnislasher_mirror_image.tscn
│   │       └── quillspray_projectile.tscn
│   ├── singletons/
│   │   ├── README.md
│   │   ├── button_sounds.gd
│   │   ├── combat_log.gd
│   │   ├── config.gd
│   │   ├── constants.gd
│   │   ├── effect.gd
│   │   ├── elapsed_timer.gd
│   │   ├── event_bus.gd
│   │   ├── experience.gd
│   │   ├── experience_password.gd
│   │   ├── globals.gd
│   │   ├── group_manager.gd
│   │   ├── item_drop_calc.gd
│   │   ├── messages.gd
│   │   ├── mission_status.gd
│   │   ├── mission_tracking.gd
│   │   ├── nakama_connection.gd
│   │   ├── player_experience.gd
│   │   ├── player_manager.gd
│   │   ├── preloads.gd
│   │   ├── properties/
│   │   │   ├── README.md
│   │   │   ├── ability_properties.gd
│   │   │   ├── aura_properties.gd
│   │   │   ├── autocast_properties.gd
│   │   │   ├── builder_properties.gd
│   │   │   ├── item_properties.gd
│   │   │   ├── mission_properties.gd
│   │   │   ├── recipe_properties.gd
│   │   │   ├── tower_properties.gd
│   │   │   ├── tutorial_properties.gd
│   │   │   ├── wave_special_properties.gd
│   │   │   └── wisdom_upgrade_properties.gd
│   │   ├── rich_texts.gd
│   │   ├── sanitize_text.gd
│   │   ├── secrets.gd
│   │   ├── settings.gd
│   │   ├── sfx.gd
│   │   ├── sfx_paths.gd
│   │   ├── tower_distribution.gd
│   │   ├── tower_sprites.gd
│   │   ├── unit_icons.gd
│   │   ├── utils.gd
│   │   ├── vector_utils.gd
│   │   └── wave_special.gd
│   ├── spells/
│   │   ├── spell_blizzard.gd
│   │   ├── spell_blizzard.tscn
│   │   ├── spell_chain_lightning.gd
│   │   ├── spell_chain_lightning.tscn
│   │   ├── spell_dummy.gd
│   │   ├── spell_dummy.tscn
│   │   ├── spell_forked_lightning.gd
│   │   ├── spell_forked_lightning.tscn
│   │   ├── spell_swarm.gd
│   │   ├── spell_swarm.tscn
│   │   └── spell_type.gd
│   ├── sprites/
│   │   ├── lightning_animation.tscn
│   │   └── pulsing_dot.tscn
│   ├── tests/
│   │   ├── README.md
│   │   ├── playtest_bot.gd
│   │   ├── test_horadric_tool.gd
│   │   ├── test_item_drop_chances.gd
│   │   ├── test_items_tool.gd
│   │   ├── test_tool.gd
│   │   ├── test_tower_sprite_size.gd
│   │   └── test_towers_tool.gd
│   ├── towers/
│   │   ├── README.md
│   │   ├── autocast.gd
│   │   ├── autocast.tscn
│   │   ├── event.gd
│   │   ├── multiboard_values.gd
│   │   ├── range_data.gd
│   │   ├── range_indicator.gd
│   │   ├── range_indicator.tscn
│   │   ├── tower.gd
│   │   ├── tower.tscn
│   │   ├── tower_behavior.gd
│   │   ├── tower_behavior_template.gd
│   │   ├── tower_behaviors/
│   │   │   ├── afflicted_obelisk.gd
│   │   │   ├── ancient_energy_converter.gd
│   │   │   ├── annoyed_tree.gd
│   │   │   ├── arcane_storm.gd
│   │   │   ├── area_roaster.gd
│   │   │   ├── ash_geyser.gd
│   │   │   ├── astral_lantern.gd
│   │   │   ├── astral_rift.gd
│   │   │   ├── baby_tuskin.gd
│   │   │   ├── ball_lightning_accelerator.gd
│   │   │   ├── basic_knowledge.gd
│   │   │   ├── black_dragon_roost.gd
│   │   │   ├── black_rock_totem.gd
│   │   │   ├── bomb_turret.gd
│   │   │   ├── bone_shrine.gd
│   │   │   ├── bonk_the_living_mountain.gd
│   │   │   ├── broken_cage.gd
│   │   │   ├── broken_circle_of_wind.gd
│   │   │   ├── broken_fire_pit.gd
│   │   │   ├── broken_lightning_rod.gd
│   │   │   ├── bronze_dragon_roost.gd
│   │   │   ├── buried_soul.gd
│   │   │   ├── burning_watchtower.gd
│   │   │   ├── burrow.gd
│   │   │   ├── caged_fire.gd
│   │   │   ├── cenarion.gd
│   │   │   ├── chaining_storm.gd
│   │   │   ├── chaos_warlock.gd
│   │   │   ├── charged_obelisk.gd
│   │   │   ├── chilled_spire.gd
│   │   │   ├── cloud_warrior.gd
│   │   │   ├── cloudy_temple_of_absorption.gd
│   │   │   ├── coconut_sapling.gd
│   │   │   ├── coin_machine.gd
│   │   │   ├── cold_obelisk.gd
│   │   │   ├── cold_troll.gd
│   │   │   ├── contraption.gd
│   │   │   ├── crimson_wyrm.gd
│   │   │   ├── cruel_fire.gd
│   │   │   ├── cursed_grounds.gd
│   │   │   ├── cute_small_spider.gd
│   │   │   ├── dark_battery.gd
│   │   │   ├── death_knight.gd
│   │   │   ├── dimensional_flux_collector.gd
│   │   │   ├── dragon_sorcerer.gd
│   │   │   ├── drake_whisperer.gd
│   │   │   ├── dreadlord.gd
│   │   │   ├── dutchmans_grave.gd
│   │   │   ├── dwarven_forgery.gd
│   │   │   ├── ebonfrost_crystal.gd
│   │   │   ├── embershell_turtle_hatchling.gd
│   │   │   ├── empty_tower_behavior.gd
│   │   │   ├── energy_junction.gd
│   │   │   ├── essence_of_fury.gd
│   │   │   ├── felweed.gd
│   │   │   ├── fenced_flames.gd
│   │   │   ├── fiery_dog.gd
│   │   │   ├── fire_battery.gd
│   │   │   ├── fire_star.gd
│   │   │   ├── firestorm_cell.gd
│   │   │   ├── fisherman.gd
│   │   │   ├── forest_archer.gd
│   │   │   ├── forest_protectress.gd
│   │   │   ├── forest_troll.gd
│   │   │   ├── frost_root.gd
│   │   │   ├── frosty_rock.gd
│   │   │   ├── frozen_well.gd
│   │   │   ├── garden_of_eden.gd
│   │   │   ├── gatling_gun.gd
│   │   │   ├── genis_sage.gd
│   │   │   ├── geothermal_extractor.gd
│   │   │   ├── glaive_master.gd
│   │   │   ├── glowing_solar_orb.gd
│   │   │   ├── gnoll_thunder_mage.gd
│   │   │   ├── goblin_stronghold.gd
│   │   │   ├── grab-o-bot.gd
│   │   │   ├── green_dragon_roost.gd
│   │   │   ├── green_lightning.gd
│   │   │   ├── greyfang.gd
│   │   │   ├── gryphon_rider.gd
│   │   │   ├── hall_of_souls.gd
│   │   │   ├── harby.gd
│   │   │   ├── harpy_witch.gd
│   │   │   ├── haunted_rubble.gd
│   │   │   ├── healing_obelisk.gd
│   │   │   ├── helicopter_zone.gd
│   │   │   ├── hell_bat.gd
│   │   │   ├── holy_energy.gd
│   │   │   ├── ice_battery.gd
│   │   │   ├── icy_core.gd
│   │   │   ├── icy_skulls.gd
│   │   │   ├── icy_spirit.gd
│   │   │   ├── igloo.gd
│   │   │   ├── inexperienced_huntress.gd
│   │   │   ├── inflamed_stone.gd
│   │   │   ├── initiate_elementalist.gd
│   │   │   ├── it.gd
│   │   │   ├── jungle_stalker.gd
│   │   │   ├── kraken.gd
│   │   │   ├── lesser_elemental_ghost.gd
│   │   │   ├── lesser_priest.gd
│   │   │   ├── lesser_skeletal_mage.gd
│   │   │   ├── lesser_wolves_den.gd
│   │   │   ├── library_of_alexandria.gd
│   │   │   ├── lich_king.gd
│   │   │   ├── lightning_eye.gd
│   │   │   ├── lightning_generator.gd
│   │   │   ├── lightning_totem.gd
│   │   │   ├── little_phoenix.gd
│   │   │   ├── living_volcano.gd
│   │   │   ├── lunar_emitter.gd
│   │   │   ├── lunar_sentinel.gd
│   │   │   ├── magic_battery.gd
│   │   │   ├── magic_mushroom.gd
│   │   │   ├── magna_warrior.gd
│   │   │   ├── mana-touched_drake.gd
│   │   │   ├── marine.gd
│   │   │   ├── meteor_totem.gd
│   │   │   ├── militia_watchtower.gd
│   │   │   ├── miner.gd
│   │   │   ├── minor_magic_ruin.gd
│   │   │   ├── mister_fireflies.gd
│   │   │   ├── monolith_of_chaos.gd
│   │   │   ├── morphling.gd
│   │   │   ├── mossy_acid_sprayer.gd
│   │   │   ├── mud_golem.gd
│   │   │   ├── nature_sprites.gd
│   │   │   ├── necromantic_altar.gd
│   │   │   ├── nortrom_the_silencer.gd
│   │   │   ├── nuclear_missile_launcher.gd
│   │   │   ├── obelisk_of_fortuity.gd
│   │   │   ├── owl_of_wisdom.gd
│   │   │   ├── particle_accelerator.gd
│   │   │   ├── phantom.gd
│   │   │   ├── plagued_crypt.gd
│   │   │   ├── planar_gate.gd
│   │   │   ├── poison_battery.gd
│   │   │   ├── polar_bear_cub.gd
│   │   │   ├── portal_to_swine_purgatory.gd
│   │   │   ├── prince_of_lightning.gd
│   │   │   ├── princess_of_light.gd
│   │   │   ├── razorboar_thornweaver.gd
│   │   │   ├── red_ball_lightning.gd
│   │   │   ├── regenerating_well.gd
│   │   │   ├── rooted_chasm.gd
│   │   │   ├── rotted_flashing_grave.gd
│   │   │   ├── rowing_boat.gd
│   │   │   ├── ruined_wind_tower.gd
│   │   │   ├── rundown_iron_sentry.gd
│   │   │   ├── sacred_altar.gd
│   │   │   ├── sacrificial_lamb.gd
│   │   │   ├── safirons_cold_grave.gd
│   │   │   ├── scales.gd
│   │   │   ├── sea_turtle.gd
│   │   │   ├── servant_of_the_twin_flames.gd
│   │   │   ├── sewer_connection.gd
│   │   │   ├── shadow.gd
│   │   │   ├── shaman.gd
│   │   │   ├── shard_of_souls.gd
│   │   │   ├── silver_knight.gd
│   │   │   ├── skink.gd
│   │   │   ├── small_bug_nest.gd
│   │   │   ├── small_fire_sprayer.gd
│   │   │   ├── small_frost_fire.gd
│   │   │   ├── small_ice_mine.gd
│   │   │   ├── small_light.gd
│   │   │   ├── small_ray_blaster.gd
│   │   │   ├── small_serpent_ward.gd
│   │   │   ├── small_torch.gd
│   │   │   ├── sniper.gd
│   │   │   ├── solar_collector.gd
│   │   │   ├── solar_emitter.gd
│   │   │   ├── sorceress.gd
│   │   │   ├── soul_vault.gd
│   │   │   ├── soulflame_device.gd
│   │   │   ├── spell_collector.gd
│   │   │   ├── spider_queen.gd
│   │   │   ├── star_gazer.gd
│   │   │   ├── storm_battery.gd
│   │   │   ├── storm_coil.gd
│   │   │   ├── storm_focus.gd
│   │   │   ├── stormy_dog.gd
│   │   │   ├── sun_crusader.gd
│   │   │   ├── taita_the_hermit.gd
│   │   │   ├── teacher.gd
│   │   │   ├── tentacle_spawn.gd
│   │   │   ├── the_conduit.gd
│   │   │   ├── the_council_of_demons.gd
│   │   │   ├── the_fire_lord.gd
│   │   │   ├── the_frozen_wyrm.gd
│   │   │   ├── the_furnace.gd
│   │   │   ├── the_omnislasher.gd
│   │   │   ├── the_steam_engine.gd
│   │   │   ├── thief_apprentice.gd
│   │   │   ├── tidewater_stream.gd
│   │   │   ├── time_manipulator.gd
│   │   │   ├── timevault.gd
│   │   │   ├── tiny_storm_lantern.gd
│   │   │   ├── tombstone.gd
│   │   │   ├── tundra_stalker.gd
│   │   │   ├── undisturbed_crypt.gd
│   │   │   ├── valor.gd
│   │   │   ├── village_witch.gd
│   │   │   ├── void_drake.gd
│   │   │   ├── vulshok_the_berserker.gd
│   │   │   ├── warrior_of_light.gd
│   │   │   ├── wild_warbeast.gd
│   │   │   ├── witch_doctor.gd
│   │   │   ├── wooden_trap.gd
│   │   │   ├── xeno_research_facility.gd
│   │   │   ├── ymir.gd
│   │   │   ├── young_northern_troll.gd
│   │   │   ├── zealot.gd
│   │   │   └── zeus.gd
│   │   ├── tower_preview.gd
│   │   ├── tower_preview.tscn
│   │   └── tower_sprites/
│   │       ├── abandoned_pit_1.tscn
│   │       ├── abandoned_pit_2.tscn
│   │       ├── abandoned_pit_3.tscn
│   │       ├── abandoned_pit_4.tscn
│   │       ├── abandoned_pit_5.tscn
│   │       ├── abominable_snowman_1.tscn
│   │       ├── abominable_snowman_2.tscn
│   │       ├── abominable_snowman_3.tscn
│   │       ├── abominable_snowman_4.tscn
│   │       ├── abominable_snowman_5.tscn
│   │       ├── afflicted_obelisk_1.tscn
│   │       ├── afflicted_obelisk_2.tscn
│   │       ├── afflicted_obelisk_3.tscn
│   │       ├── afflicted_obelisk_4.tscn
│   │       ├── ancient_energy_converter_1.tscn
│   │       ├── annoyed_tree_1.tscn
│   │       ├── annoyed_tree_2.tscn
│   │       ├── annoyed_tree_3.tscn
│   │       ├── annoyed_tree_4.tscn
│   │       ├── arcane_storm_1.tscn
│   │       ├── area_roaster_1.tscn
│   │       ├── area_roaster_2.tscn
│   │       ├── area_roaster_3.tscn
│   │       ├── ash_geyser_1.tscn
│   │       ├── ash_geyser_2.tscn
│   │       ├── ash_geyser_3.tscn
│   │       ├── ash_geyser_4.tscn
│   │       ├── ash_geyser_5.tscn
│   │       ├── astral_lantern_1.tscn
│   │       ├── astral_lantern_2.tscn
│   │       ├── astral_lantern_3.tscn
│   │       ├── astral_lantern_4.tscn
│   │       ├── astral_rift_1.tscn
│   │       ├── baby_plant_1.tscn
│   │       ├── baby_plant_2.tscn
│   │       ├── baby_plant_3.tscn
│   │       ├── baby_plant_4.tscn
│   │       ├── baby_plant_5.tscn
│   │       ├── baby_plant_6.tscn
│   │       ├── baby_tuskin_1.tscn
│   │       ├── baby_tuskin_2.tscn
│   │       ├── baby_tuskin_3.tscn
│   │       ├── ball_lightning_accelerator_1.tscn
│   │       ├── ball_lightning_accelerator_2.tscn
│   │       ├── basic_knowledge_1.tscn
│   │       ├── basic_knowledge_2.tscn
│   │       ├── basic_knowledge_3.tscn
│   │       ├── basic_knowledge_4.tscn
│   │       ├── basic_knowledge_5.tscn
│   │       ├── black_dragon_roost_1.tscn
│   │       ├── black_rock_totem_1.tscn
│   │       ├── bomb_turret_1.tscn
│   │       ├── bomb_turret_2.tscn
│   │       ├── bone_shrine_1.tscn
│   │       ├── bone_shrine_2.tscn
│   │       ├── bone_shrine_3.tscn
│   │       ├── bonk_the_living_mountain_1.tscn
│   │       ├── broken_cage_1.tscn
│   │       ├── broken_cage_2.tscn
│   │       ├── broken_cage_3.tscn
│   │       ├── broken_cage_4.tscn
│   │       ├── broken_cage_5.tscn
│   │       ├── broken_circle_of_wind_1.tscn
│   │       ├── broken_circle_of_wind_2.tscn
│   │       ├── broken_circle_of_wind_3.tscn
│   │       ├── broken_circle_of_wind_4.tscn
│   │       ├── broken_circle_of_wind_5.tscn
│   │       ├── broken_fire_pit_1.tscn
│   │       ├── broken_fire_pit_2.tscn
│   │       ├── broken_fire_pit_3.tscn
│   │       ├── broken_fire_pit_4.tscn
│   │       ├── broken_fire_pit_5.tscn
│   │       ├── broken_lightning_rod_1.tscn
│   │       ├── broken_lightning_rod_2.tscn
│   │       ├── broken_lightning_rod_3.tscn
│   │       ├── broken_lightning_rod_4.tscn
│   │       ├── broken_lightning_rod_5.tscn
│   │       ├── bronze_dragon_roost_1.tscn
│   │       ├── buried_soul_1.tscn
│   │       ├── buried_soul_2.tscn
│   │       ├── buried_soul_3.tscn
│   │       ├── buried_soul_4.tscn
│   │       ├── burning_watchtower_1.tscn
│   │       ├── burning_watchtower_2.tscn
│   │       ├── burning_watchtower_3.tscn
│   │       ├── burning_watchtower_4.tscn
│   │       ├── burrow_1.tscn
│   │       ├── burrow_2.tscn
│   │       ├── burrow_3.tscn
│   │       ├── burrow_4.tscn
│   │       ├── caged_fire_1.tscn
│   │       ├── caged_fire_2.tscn
│   │       ├── cenarion_1.tscn
│   │       ├── chaining_storm_1.tscn
│   │       ├── chaos_warlock_1.tscn
│   │       ├── chaos_warlock_2.tscn
│   │       ├── charged_obelisk_1.tscn
│   │       ├── chilled_spire_1.tscn
│   │       ├── chilled_spire_2.tscn
│   │       ├── cloud_warrior_1.tscn
│   │       ├── cloud_warrior_2.tscn
│   │       ├── cloud_warrior_3.tscn
│   │       ├── cloud_warrior_4.tscn
│   │       ├── cloud_warrior_5.tscn
│   │       ├── cloudy_temple_of_absorption_1.tscn
│   │       ├── coconut_sapling_1.tscn
│   │       ├── coconut_sapling_2.tscn
│   │       ├── coin_machine_1.tscn
│   │       ├── coin_machine_2.tscn
│   │       ├── cold_obelisk_1.tscn
│   │       ├── cold_obelisk_2.tscn
│   │       ├── cold_obelisk_3.tscn
│   │       ├── cold_troll_1.tscn
│   │       ├── cold_troll_2.tscn
│   │       ├── cold_troll_3.tscn
│   │       ├── cold_troll_4.tscn
│   │       ├── contraption_1.tscn
│   │       ├── contraption_2.tscn
│   │       ├── contraption_3.tscn
│   │       ├── contraption_4.tscn
│   │       ├── crimson_wyrm_1.tscn
│   │       ├── cruel_fire_1.tscn
│   │       ├── cruel_fire_2.tscn
│   │       ├── cruel_fire_3.tscn
│   │       ├── cursed_grounds_1.tscn
│   │       ├── cursed_grounds_2.tscn
│   │       ├── cursed_grounds_3.tscn
│   │       ├── cute_small_spider_1.tscn
│   │       ├── cute_small_spider_2.tscn
│   │       ├── cute_small_spider_3.tscn
│   │       ├── cute_small_spider_4.tscn
│   │       ├── dark_battery_1.tscn
│   │       ├── dark_battery_2.tscn
│   │       ├── dark_battery_3.tscn
│   │       ├── dark_fire_pit_1.tscn
│   │       ├── dark_fire_pit_2.tscn
│   │       ├── dark_fire_pit_3.tscn
│   │       ├── dark_fire_pit_4.tscn
│   │       ├── dark_fire_pit_5.tscn
│   │       ├── death_knight_1.tscn
│   │       ├── dimensional_flux_collector_1.tscn
│   │       ├── dragon_sorcerer_1.tscn
│   │       ├── drake_whisperer_1.tscn
│   │       ├── dreadlord_1.tscn
│   │       ├── dutchmans_grave_1.tscn
│   │       ├── dwarven_forgery_1.tscn
│   │       ├── ebonfrost_crystal_1.tscn
│   │       ├── embershell_turtle_hatchling_1.tscn
│   │       ├── embershell_turtle_hatchling_2.tscn
│   │       ├── embershell_turtle_hatchling_3.tscn
│   │       ├── embershell_turtle_hatchling_4.tscn
│   │       ├── embershell_turtle_hatchling_5.tscn
│   │       ├── energy_junction_1.tscn
│   │       ├── energy_junction_2.tscn
│   │       ├── energy_junction_3.tscn
│   │       ├── essence_of_fury_1.tscn
│   │       ├── essence_of_fury_2.tscn
│   │       ├── essence_of_fury_3.tscn
│   │       ├── essence_of_fury_4.tscn
│   │       ├── essence_of_fury_5.tscn
│   │       ├── felweed_1.tscn
│   │       ├── felweed_2.tscn
│   │       ├── felweed_3.tscn
│   │       ├── felweed_4.tscn
│   │       ├── felweed_5.tscn
│   │       ├── felweed_6.tscn
│   │       ├── fenced_flames_1.tscn
│   │       ├── fenced_flames_2.tscn
│   │       ├── fenced_flames_3.tscn
│   │       ├── fenced_flames_4.tscn
│   │       ├── fiery_dog_1.tscn
│   │       ├── fiery_dog_2.tscn
│   │       ├── fiery_dog_3.tscn
│   │       ├── fiery_dog_4.tscn
│   │       ├── fiery_dog_5.tscn
│   │       ├── fiery_pebble_1.tscn
│   │       ├── fiery_pebble_2.tscn
│   │       ├── fiery_pebble_3.tscn
│   │       ├── fiery_pebble_4.tscn
│   │       ├── fiery_pebble_5.tscn
│   │       ├── fiery_pebble_6.tscn
│   │       ├── fire_battery_1.tscn
│   │       ├── fire_battery_2.tscn
│   │       ├── fire_battery_3.tscn
│   │       ├── fire_star_1.tscn
│   │       ├── firestorm_cell_1.tscn
│   │       ├── firestorm_cell_2.tscn
│   │       ├── firestorm_cell_3.tscn
│   │       ├── firestorm_cell_4.tscn
│   │       ├── fisherman_1.tscn
│   │       ├── forest_archer_1.tscn
│   │       ├── forest_archer_2.tscn
│   │       ├── forest_archer_3.tscn
│   │       ├── forest_protectress_1.tscn
│   │       ├── forest_troll_1.tscn
│   │       ├── forest_troll_2.tscn
│   │       ├── forest_troll_3.tscn
│   │       ├── frost_root_1.tscn
│   │       ├── frost_root_2.tscn
│   │       ├── frost_root_3.tscn
│   │       ├── frost_root_4.tscn
│   │       ├── frost_root_5.tscn
│   │       ├── frost_root_6.tscn
│   │       ├── frosty_rock_1.tscn
│   │       ├── frosty_rock_2.tscn
│   │       ├── frosty_rock_3.tscn
│   │       ├── frosty_rock_4.tscn
│   │       ├── frozen_well_1.tscn
│   │       ├── garden_of_eden_1.tscn
│   │       ├── gatling_gun_1.tscn
│   │       ├── genis_sage_1.tscn
│   │       ├── geothermal_extractor_1.tscn
│   │       ├── geothermal_extractor_2.tscn
│   │       ├── glaive_master_1.tscn
│   │       ├── glowing_solar_orb_1.tscn
│   │       ├── glowing_solar_orb_2.tscn
│   │       ├── glowing_solar_orb_3.tscn
│   │       ├── glowing_solar_orb_4.tscn
│   │       ├── glowing_solar_orb_5.tscn
│   │       ├── gnoll_thunder_mage_1.tscn
│   │       ├── gnoll_thunder_mage_2.tscn
│   │       ├── gnoll_thunder_mage_3.tscn
│   │       ├── goblin_stronghold_1.tscn
│   │       ├── grab-o-bot_1.tscn
│   │       ├── green_dragon_roost_1.tscn
│   │       ├── green_lightning_1.tscn
│   │       ├── green_lightning_2.tscn
│   │       ├── green_lightning_3.tscn
│   │       ├── green_lightning_4.tscn
│   │       ├── greyfang_1.tscn
│   │       ├── gryphon_rider_1.tscn
│   │       ├── hall_of_souls_1.tscn
│   │       ├── hall_of_souls_2.tscn
│   │       ├── hall_of_souls_3.tscn
│   │       ├── harby_1.tscn
│   │       ├── harpy_witch_1.tscn
│   │       ├── harpy_witch_2.tscn
│   │       ├── haunted_rubble_1.tscn
│   │       ├── haunted_rubble_2.tscn
│   │       ├── haunted_rubble_3.tscn
│   │       ├── haunted_rubble_4.tscn
│   │       ├── haunted_rubble_5.tscn
│   │       ├── healing_obelisk_1.tscn
│   │       ├── healing_obelisk_2.tscn
│   │       ├── healing_obelisk_3.tscn
│   │       ├── healing_obelisk_4.tscn
│   │       ├── helicopter_zone_1.tscn
│   │       ├── hell_bat_1.tscn
│   │       ├── hell_bat_2.tscn
│   │       ├── hell_bat_3.tscn
│   │       ├── holy_energy_1.tscn
│   │       ├── ice_battery_1.tscn
│   │       ├── ice_battery_2.tscn
│   │       ├── ice_battery_3.tscn
│   │       ├── icy_core_1.tscn
│   │       ├── icy_core_2.tscn
│   │       ├── icy_skulls_1.tscn
│   │       ├── icy_skulls_2.tscn
│   │       ├── icy_skulls_3.tscn
│   │       ├── icy_skulls_4.tscn
│   │       ├── icy_spirit_1.tscn
│   │       ├── icy_spirit_2.tscn
│   │       ├── icy_spirit_3.tscn
│   │       ├── igloo_1.tscn
│   │       ├── igloo_2.tscn
│   │       ├── igloo_3.tscn
│   │       ├── inexperienced_huntress_1.tscn
│   │       ├── inexperienced_huntress_2.tscn
│   │       ├── inexperienced_huntress_3.tscn
│   │       ├── inflamed_stone_1.tscn
│   │       ├── inflamed_stone_2.tscn
│   │       ├── inflamed_stone_3.tscn
│   │       ├── initiate_elementalist_1.tscn
│   │       ├── initiate_elementalist_2.tscn
│   │       ├── initiate_elementalist_3.tscn
│   │       ├── initiate_elementalist_4.tscn
│   │       ├── it_1.tscn
│   │       ├── jungle_stalker_1.tscn
│   │       ├── jungle_stalker_2.tscn
│   │       ├── jungle_stalker_3.tscn
│   │       ├── kraken_1.tscn
│   │       ├── lesser_astral_defender_1.tscn
│   │       ├── lesser_astral_defender_2.tscn
│   │       ├── lesser_astral_defender_3.tscn
│   │       ├── lesser_astral_defender_4.tscn
│   │       ├── lesser_astral_defender_5.tscn
│   │       ├── lesser_dark_defender_1.tscn
│   │       ├── lesser_dark_defender_2.tscn
│   │       ├── lesser_dark_defender_3.tscn
│   │       ├── lesser_dark_defender_4.tscn
│   │       ├── lesser_dark_defender_5.tscn
│   │       ├── lesser_elemental_ghost_1.tscn
│   │       ├── lesser_elemental_ghost_2.tscn
│   │       ├── lesser_elemental_ghost_3.tscn
│   │       ├── lesser_elemental_ghost_4.tscn
│   │       ├── lesser_elemental_ghost_5.tscn
│   │       ├── lesser_flamy_defender_1.tscn
│   │       ├── lesser_flamy_defender_2.tscn
│   │       ├── lesser_flamy_defender_3.tscn
│   │       ├── lesser_flamy_defender_4.tscn
│   │       ├── lesser_flamy_defender_5.tscn
│   │       ├── lesser_ice_defender_1.tscn
│   │       ├── lesser_ice_defender_2.tscn
│   │       ├── lesser_ice_defender_3.tscn
│   │       ├── lesser_ice_defender_4.tscn
│   │       ├── lesser_ice_defender_5.tscn
│   │       ├── lesser_iron_defender_1.tscn
│   │       ├── lesser_iron_defender_2.tscn
│   │       ├── lesser_iron_defender_3.tscn
│   │       ├── lesser_iron_defender_4.tscn
│   │       ├── lesser_iron_defender_5.tscn
│   │       ├── lesser_natural_defender_1.tscn
│   │       ├── lesser_natural_defender_2.tscn
│   │       ├── lesser_natural_defender_3.tscn
│   │       ├── lesser_natural_defender_4.tscn
│   │       ├── lesser_natural_defender_5.tscn
│   │       ├── lesser_priest_1.tscn
│   │       ├── lesser_priest_2.tscn
│   │       ├── lesser_priest_3.tscn
│   │       ├── lesser_priest_4.tscn
│   │       ├── lesser_priest_5.tscn
│   │       ├── lesser_skeletal_mage_1.tscn
│   │       ├── lesser_skeletal_mage_2.tscn
│   │       ├── lesser_skeletal_mage_3.tscn
│   │       ├── lesser_skeletal_mage_4.tscn
│   │       ├── lesser_storm_defender_1.tscn
│   │       ├── lesser_storm_defender_2.tscn
│   │       ├── lesser_storm_defender_3.tscn
│   │       ├── lesser_storm_defender_4.tscn
│   │       ├── lesser_storm_defender_5.tscn
│   │       ├── lesser_wolves_den_1.tscn
│   │       ├── lesser_wolves_den_2.tscn
│   │       ├── lesser_wolves_den_3.tscn
│   │       ├── library_of_alexandria_1.tscn
│   │       ├── lich_king_1.tscn
│   │       ├── lightning_eye_1.tscn
│   │       ├── lightning_generator_1.tscn
│   │       ├── lightning_generator_2.tscn
│   │       ├── lightning_generator_3.tscn
│   │       ├── lightning_generator_4.tscn
│   │       ├── lightning_totem_1.tscn
│   │       ├── lightning_totem_2.tscn
│   │       ├── lightning_totem_3.tscn
│   │       ├── little_phoenix_1.tscn
│   │       ├── little_phoenix_2.tscn
│   │       ├── little_phoenix_3.tscn
│   │       ├── living_volcano_1.tscn
│   │       ├── lunar_emitter_1.tscn
│   │       ├── lunar_emitter_2.tscn
│   │       ├── lunar_sentinel_1.tscn
│   │       ├── lunar_sentinel_2.tscn
│   │       ├── lunar_sentinel_3.tscn
│   │       ├── lunar_sentinel_4.tscn
│   │       ├── magic_battery_1.tscn
│   │       ├── magic_battery_2.tscn
│   │       ├── magic_battery_3.tscn
│   │       ├── magic_mushroom_1.tscn
│   │       ├── magna_warrior_1.tscn
│   │       ├── magna_warrior_2.tscn
│   │       ├── magna_warrior_3.tscn
│   │       ├── magna_warrior_4.tscn
│   │       ├── magna_warrior_5.tscn
│   │       ├── mana-touched_drake_1.tscn
│   │       ├── mana-touched_drake_2.tscn
│   │       ├── mana-touched_drake_3.tscn
│   │       ├── mana-touched_drake_4.tscn
│   │       ├── marine_1.tscn
│   │       ├── marine_2.tscn
│   │       ├── meteor_totem_1.tscn
│   │       ├── militia_watchtower_1.tscn
│   │       ├── militia_watchtower_2.tscn
│   │       ├── militia_watchtower_3.tscn
│   │       ├── militia_watchtower_4.tscn
│   │       ├── miner_1.tscn
│   │       ├── miner_2.tscn
│   │       ├── miner_3.tscn
│   │       ├── minor_magic_ruin_1.tscn
│   │       ├── minor_magic_ruin_2.tscn
│   │       ├── minor_magic_ruin_3.tscn
│   │       ├── minor_magic_ruin_4.tscn
│   │       ├── minor_magic_ruin_5.tscn
│   │       ├── minor_magic_ruin_6.tscn
│   │       ├── mister_fireflies_1.tscn
│   │       ├── mister_fireflies_2.tscn
│   │       ├── mister_fireflies_3.tscn
│   │       ├── monolith_of_chaos_1.tscn
│   │       ├── morphling_1.tscn
│   │       ├── mossy_acid_sprayer_1.tscn
│   │       ├── mossy_acid_sprayer_2.tscn
│   │       ├── mossy_acid_sprayer_3.tscn
│   │       ├── mossy_acid_sprayer_4.tscn
│   │       ├── mossy_acid_sprayer_5.tscn
│   │       ├── mud_golem_1.tscn
│   │       ├── nature_sprites_1.tscn
│   │       ├── nature_sprites_2.tscn
│   │       ├── nature_sprites_3.tscn
│   │       ├── necromantic_altar_1.tscn
│   │       ├── necromantic_altar_2.tscn
│   │       ├── necromantic_altar_3.tscn
│   │       ├── necromantic_altar_4.tscn
│   │       ├── nortrom_the_silencer_1.tscn
│   │       ├── nuclear_missile_launcher_1.tscn
│   │       ├── obelisk_of_fortuity_1.tscn
│   │       ├── obelisk_of_fortuity_2.tscn
│   │       ├── obelisk_of_fortuity_3.tscn
│   │       ├── obelisk_of_fortuity_4.tscn
│   │       ├── obelisk_of_fortuity_5.tscn
│   │       ├── owl_of_wisdom_1.tscn
│   │       ├── owl_of_wisdom_2.tscn
│   │       ├── particle_accelerator_1.tscn
│   │       ├── particle_accelerator_2.tscn
│   │       ├── particle_accelerator_3.tscn
│   │       ├── phantom_1.tscn
│   │       ├── phantom_2.tscn
│   │       ├── phantom_3.tscn
│   │       ├── phantom_4.tscn
│   │       ├── phantom_5.tscn
│   │       ├── plagued_crypt_1.tscn
│   │       ├── planar_gate_1.tscn
│   │       ├── poison_battery_1.tscn
│   │       ├── poison_battery_2.tscn
│   │       ├── poison_battery_3.tscn
│   │       ├── polar_bear_cub_1.tscn
│   │       ├── polar_bear_cub_2.tscn
│   │       ├── polar_bear_cub_3.tscn
│   │       ├── portal_to_swine_purgatory_1.tscn
│   │       ├── portal_to_swine_purgatory_2.tscn
│   │       ├── portal_to_swine_purgatory_3.tscn
│   │       ├── prince_of_lightning_1.tscn
│   │       ├── prince_of_lightning_2.tscn
│   │       ├── princess_of_light_1.tscn
│   │       ├── princess_of_light_2.tscn
│   │       ├── razorboar_thornweaver_1.tscn
│   │       ├── razorboar_thornweaver_2.tscn
│   │       ├── razorboar_thornweaver_3.tscn
│   │       ├── red_ball_lightning_1.tscn
│   │       ├── red_ball_lightning_2.tscn
│   │       ├── regenerating_well_1.tscn
│   │       ├── regenerating_well_2.tscn
│   │       ├── regenerating_well_3.tscn
│   │       ├── rooted_chasm_1.tscn
│   │       ├── rooted_chasm_2.tscn
│   │       ├── rooted_chasm_3.tscn
│   │       ├── rooted_chasm_4.tscn
│   │       ├── rotted_flashing_grave_1.tscn
│   │       ├── rotted_flashing_grave_2.tscn
│   │       ├── rotted_flashing_grave_3.tscn
│   │       ├── rotted_flashing_grave_4.tscn
│   │       ├── rotted_flashing_grave_5.tscn
│   │       ├── rotted_flashing_grave_6.tscn
│   │       ├── rowing_boat_1.tscn
│   │       ├── rowing_boat_2.tscn
│   │       ├── rowing_boat_3.tscn
│   │       ├── rowing_boat_4.tscn
│   │       ├── ruined_monolith_1.tscn
│   │       ├── ruined_monolith_2.tscn
│   │       ├── ruined_monolith_3.tscn
│   │       ├── ruined_monolith_4.tscn
│   │       ├── ruined_monolith_5.tscn
│   │       ├── ruined_monolith_6.tscn
│   │       ├── ruined_storm_cap_1.tscn
│   │       ├── ruined_storm_cap_2.tscn
│   │       ├── ruined_storm_cap_3.tscn
│   │       ├── ruined_storm_cap_4.tscn
│   │       ├── ruined_storm_cap_5.tscn
│   │       ├── ruined_storm_cap_6.tscn
│   │       ├── ruined_sun_pedestal_1.tscn
│   │       ├── ruined_sun_pedestal_2.tscn
│   │       ├── ruined_sun_pedestal_3.tscn
│   │       ├── ruined_sun_pedestal_4.tscn
│   │       ├── ruined_sun_pedestal_5.tscn
│   │       ├── ruined_sun_pedestal_6.tscn
│   │       ├── ruined_sun_pedestal_7.tscn
│   │       ├── ruined_wind_tower_1.tscn
│   │       ├── ruined_wind_tower_2.tscn
│   │       ├── ruined_wind_tower_3.tscn
│   │       ├── ruined_wind_tower_4.tscn
│   │       ├── rundown_iron_sentry_1.tscn
│   │       ├── rundown_iron_sentry_2.tscn
│   │       ├── rundown_iron_sentry_3.tscn
│   │       ├── sacred_altar_1.tscn
│   │       ├── sacrificial_lamb_1.tscn
│   │       ├── sacrificial_lamb_2.tscn
│   │       ├── safirons_cold_grave_1.tscn
│   │       ├── scales_1.tscn
│   │       ├── sea_turtle_1.tscn
│   │       ├── sea_turtle_2.tscn
│   │       ├── sea_turtle_3.tscn
│   │       ├── servant_of_the_twin_flames_1.tscn
│   │       ├── servant_of_the_twin_flames_2.tscn
│   │       ├── sewer_connection_1.tscn
│   │       ├── sewer_connection_2.tscn
│   │       ├── sewer_connection_3.tscn
│   │       ├── sewer_connection_4.tscn
│   │       ├── shadow_1.tscn
│   │       ├── shaman_1.tscn
│   │       ├── shaman_2.tscn
│   │       ├── shaman_3.tscn
│   │       ├── shard_of_souls_1.tscn
│   │       ├── shard_of_souls_2.tscn
│   │       ├── silver_knight_1.tscn
│   │       ├── silver_knight_2.tscn
│   │       ├── skink_1.tscn
│   │       ├── skink_2.tscn
│   │       ├── skink_3.tscn
│   │       ├── skink_4.tscn
│   │       ├── skink_5.tscn
│   │       ├── small_brazier_1.tscn
│   │       ├── small_brazier_2.tscn
│   │       ├── small_brazier_3.tscn
│   │       ├── small_brazier_4.tscn
│   │       ├── small_bug_nest_1.tscn
│   │       ├── small_bug_nest_2.tscn
│   │       ├── small_bug_nest_3.tscn
│   │       ├── small_bug_nest_4.tscn
│   │       ├── small_cactus_1.tscn
│   │       ├── small_cactus_2.tscn
│   │       ├── small_cactus_3.tscn
│   │       ├── small_cactus_4.tscn
│   │       ├── small_cactus_5.tscn
│   │       ├── small_cactus_6.tscn
│   │       ├── small_fire_sprayer_1.tscn
│   │       ├── small_fire_sprayer_2.tscn
│   │       ├── small_fire_sprayer_3.tscn
│   │       ├── small_fire_sprayer_4.tscn
│   │       ├── small_fire_sprayer_5.tscn
│   │       ├── small_fire_sprayer_6.tscn
│   │       ├── small_frost_fire_1.tscn
│   │       ├── small_frost_fire_2.tscn
│   │       ├── small_frost_fire_3.tscn
│   │       ├── small_frost_fire_4.tscn
│   │       ├── small_frost_fire_5.tscn
│   │       ├── small_frozen_mushroom_1.tscn
│   │       ├── small_frozen_mushroom_2.tscn
│   │       ├── small_frozen_mushroom_3.tscn
│   │       ├── small_frozen_mushroom_4.tscn
│   │       ├── small_frozen_mushroom_5.tscn
│   │       ├── small_ice_mine_1.tscn
│   │       ├── small_ice_mine_2.tscn
│   │       ├── small_ice_mine_3.tscn
│   │       ├── small_ice_mine_4.tscn
│   │       ├── small_light_1.tscn
│   │       ├── small_light_2.tscn
│   │       ├── small_light_3.tscn
│   │       ├── small_light_4.tscn
│   │       ├── small_light_5.tscn
│   │       ├── small_pocket_rocket_1.tscn
│   │       ├── small_pocket_rocket_2.tscn
│   │       ├── small_pocket_rocket_3.tscn
│   │       ├── small_pocket_rocket_4.tscn
│   │       ├── small_pocket_rocket_5.tscn
│   │       ├── small_ray_blaster_1.tscn
│   │       ├── small_ray_blaster_2.tscn
│   │       ├── small_ray_blaster_3.tscn
│   │       ├── small_ray_blaster_4.tscn
│   │       ├── small_ray_blaster_5.tscn
│   │       ├── small_serpent_ward_1.tscn
│   │       ├── small_serpent_ward_2.tscn
│   │       ├── small_serpent_ward_3.tscn
│   │       ├── small_serpent_ward_4.tscn
│   │       ├── small_torch_1.tscn
│   │       ├── small_torch_2.tscn
│   │       ├── small_torch_3.tscn
│   │       ├── small_torch_4.tscn
│   │       ├── small_torch_5.tscn
│   │       ├── sniper_1.tscn
│   │       ├── sniper_2.tscn
│   │       ├── sniper_3.tscn
│   │       ├── sniper_4.tscn
│   │       ├── snowy_pebble_1.tscn
│   │       ├── snowy_pebble_2.tscn
│   │       ├── snowy_pebble_3.tscn
│   │       ├── snowy_pebble_4.tscn
│   │       ├── snowy_pebble_5.tscn
│   │       ├── snowy_pebble_6.tscn
│   │       ├── solar_collector_1.tscn
│   │       ├── solar_collector_2.tscn
│   │       ├── solar_emitter_1.tscn
│   │       ├── solar_emitter_2.tscn
│   │       ├── sorceress_1.tscn
│   │       ├── soul_vault_1.tscn
│   │       ├── soulflame_device_1.tscn
│   │       ├── spell_collector_1.tscn
│   │       ├── spell_collector_2.tscn
│   │       ├── spider_queen_1.tscn
│   │       ├── star_gazer_1.tscn
│   │       ├── star_gazer_2.tscn
│   │       ├── star_gazer_3.tscn
│   │       ├── star_gazer_4.tscn
│   │       ├── storm_battery_1.tscn
│   │       ├── storm_battery_2.tscn
│   │       ├── storm_battery_3.tscn
│   │       ├── storm_coil_1.tscn
│   │       ├── storm_focus_1.tscn
│   │       ├── stormy_dog_1.tscn
│   │       ├── stormy_dog_2.tscn
│   │       ├── stormy_dog_3.tscn
│   │       ├── stormy_dog_4.tscn
│   │       ├── stormy_dog_5.tscn
│   │       ├── sun_crusader_1.tscn
│   │       ├── sun_crusader_2.tscn
│   │       ├── taita_the_hermit_1.tscn
│   │       ├── teacher_1.tscn
│   │       ├── teacher_2.tscn
│   │       ├── teacher_3.tscn
│   │       ├── teacher_4.tscn
│   │       ├── teacher_5.tscn
│   │       ├── teacher_6.tscn
│   │       ├── tentacle_spawn_1.tscn
│   │       ├── tentacle_spawn_2.tscn
│   │       ├── tentacle_spawn_3.tscn
│   │       ├── tentacle_spawn_4.tscn
│   │       ├── tentacle_spawn_5.tscn
│   │       ├── tentacle_spawn_6.tscn
│   │       ├── the_conduit_1.tscn
│   │       ├── the_council_of_demons_1.tscn
│   │       ├── the_fire_lord_1.tscn
│   │       ├── the_frozen_wyrm_1.tscn
│   │       ├── the_furnace_1.tscn
│   │       ├── the_omnislasher_1.tscn
│   │       ├── the_steam_engine_1.tscn
│   │       ├── thief_apprentice_1.tscn
│   │       ├── thief_apprentice_2.tscn
│   │       ├── thief_apprentice_3.tscn
│   │       ├── thief_apprentice_4.tscn
│   │       ├── thief_apprentice_5.tscn
│   │       ├── tidewater_stream_1.tscn
│   │       ├── time_manipulator_1.tscn
│   │       ├── timevault_1.tscn
│   │       ├── tiny_shrub_1.tscn
│   │       ├── tiny_shrub_2.tscn
│   │       ├── tiny_shrub_3.tscn
│   │       ├── tiny_shrub_4.tscn
│   │       ├── tiny_shrub_5.tscn
│   │       ├── tiny_shrub_6.tscn
│   │       ├── tiny_storm_lantern_1.tscn
│   │       ├── tiny_storm_lantern_2.tscn
│   │       ├── tiny_storm_lantern_3.tscn
│   │       ├── tiny_storm_lantern_4.tscn
│   │       ├── tombstone_1.tscn
│   │       ├── tombstone_2.tscn
│   │       ├── tombstone_3.tscn
│   │       ├── tombstone_4.tscn
│   │       ├── tombstone_5.tscn
│   │       ├── tombstone_6.tscn
│   │       ├── trash_heap_1.tscn
│   │       ├── trash_heap_2.tscn
│   │       ├── trash_heap_3.tscn
│   │       ├── trash_heap_4.tscn
│   │       ├── trash_heap_5.tscn
│   │       ├── trash_heap_6.tscn
│   │       ├── tree_stump_1.tscn
│   │       ├── tree_stump_2.tscn
│   │       ├── tree_stump_3.tscn
│   │       ├── tree_stump_4.tscn
│   │       ├── tree_stump_5.tscn
│   │       ├── tundra_stalker_1.tscn
│   │       ├── tundra_stalker_2.tscn
│   │       ├── tundra_stalker_3.tscn
│   │       ├── tundra_stalker_4.tscn
│   │       ├── tundra_stalker_5.tscn
│   │       ├── undisturbed_crypt_1.tscn
│   │       ├── undisturbed_crypt_2.tscn
│   │       ├── undisturbed_crypt_3.tscn
│   │       ├── undisturbed_crypt_4.tscn
│   │       ├── valor_1.tscn
│   │       ├── village_witch_1.tscn
│   │       ├── village_witch_2.tscn
│   │       ├── village_witch_3.tscn
│   │       ├── village_witch_4.tscn
│   │       ├── void_drake_1.tscn
│   │       ├── void_drake_2.tscn
│   │       ├── vulshok_the_berserker_1.tscn
│   │       ├── warrior_of_light_1.tscn
│   │       ├── warrior_of_light_2.tscn
│   │       ├── warrior_of_light_3.tscn
│   │       ├── wild_warbeast_1.tscn
│   │       ├── witch_doctor_1.tscn
│   │       ├── wooden_trap_1.tscn
│   │       ├── wooden_trap_2.tscn
│   │       ├── wooden_trap_3.tscn
│   │       ├── wooden_trap_4.tscn
│   │       ├── wooden_trap_5.tscn
│   │       ├── xeno_research_facility_1.tscn
│   │       ├── ymir_1.tscn
│   │       ├── young_northern_troll_1.tscn
│   │       ├── young_northern_troll_2.tscn
│   │       ├── young_northern_troll_3.tscn
│   │       ├── zealot_1.tscn
│   │       ├── zealot_2.tscn
│   │       ├── zealot_3.tscn
│   │       ├── zealot_4.tscn
│   │       └── zeus_1.tscn
│   ├── ui/
│   │   ├── buttons/
│   │   │   ├── ability_button.gd
│   │   │   ├── ability_button.tscn
│   │   │   ├── auto_mode_indicator.gd
│   │   │   ├── auto_mode_indicator.tscn
│   │   │   ├── autocast_button.gd
│   │   │   ├── autocast_button.tscn
│   │   │   ├── buff_group_button.gd
│   │   │   ├── buff_group_button.tscn
│   │   │   ├── builder_button.tscn
│   │   │   ├── button_tooltip.gd
│   │   │   ├── button_tooltip.tscn
│   │   │   ├── button_with_rich_tooltip.gd
│   │   │   ├── element_button.gd
│   │   │   ├── element_button.tscn
│   │   │   ├── empty_unit_button.gd
│   │   │   ├── empty_unit_button.tscn
│   │   │   ├── freshness_indicator.gd
│   │   │   ├── freshness_indicator.tscn
│   │   │   ├── inventory_slot_button.tscn
│   │   │   ├── item_button.gd
│   │   │   ├── item_button.tscn
│   │   │   ├── item_button_inner.gd
│   │   │   ├── menu_expanding_button.gd
│   │   │   ├── menu_expanding_button.tscn
│   │   │   ├── rarity_background.gd
│   │   │   ├── rarity_background.tscn
│   │   │   ├── recipe_button.gd
│   │   │   ├── recipe_button.tscn
│   │   │   ├── speed_button.tscn
│   │   │   ├── time_indicator.gd
│   │   │   ├── time_indicator.tscn
│   │   │   ├── tower_button.gd
│   │   │   ├── tower_button.tscn
│   │   │   ├── wisdom_upgrade_button.gd
│   │   │   └── wisdom_upgrade_button.tscn
│   │   ├── dev_controls/
│   │   │   ├── dev_controls.gd
│   │   │   ├── dev_controls.tscn
│   │   │   ├── signals_control.gd
│   │   │   ├── signals_control.tscn
│   │   │   ├── wave_control.gd
│   │   │   └── wave_control.tscn
│   │   ├── filter_buttons/
│   │   │   ├── element_filter.gd
│   │   │   ├── element_filter.tscn
│   │   │   ├── filter_button.tscn
│   │   │   ├── filter_button_element.gd
│   │   │   ├── filter_button_element.tscn
│   │   │   ├── filter_button_item_type.gd
│   │   │   ├── filter_button_item_type.tscn
│   │   │   ├── filter_button_rarity.gd
│   │   │   ├── filter_button_rarity.tscn
│   │   │   ├── item_type_filter.gd
│   │   │   ├── item_type_filter.tscn
│   │   │   ├── rarity_filter.gd
│   │   │   └── rarity_filter.tscn
│   │   ├── game_menu/
│   │   │   ├── credits_menu.gd
│   │   │   ├── credits_menu.tscn
│   │   │   ├── game_menu.gd
│   │   │   ├── game_menu.tscn
│   │   │   ├── help_menu.gd
│   │   │   ├── help_menu.tscn
│   │   │   ├── help_menu_tab.gd
│   │   │   ├── help_menu_tab.tscn
│   │   │   ├── settings_menu.gd
│   │   │   └── settings_menu.tscn
│   │   ├── hud/
│   │   │   ├── OneTimeHelpPopup.tscn
│   │   │   ├── build_version_label.gd
│   │   │   ├── build_version_label.tscn
│   │   │   ├── builder_menu.gd
│   │   │   ├── builder_menu.tscn
│   │   │   ├── combat_log_window.gd
│   │   │   ├── combat_log_window.tscn
│   │   │   ├── desync_indicator.tscn
│   │   │   ├── elements_menu.gd
│   │   │   ├── elements_menu.tscn
│   │   │   ├── floating_text.gd
│   │   │   ├── floating_text.tscn
│   │   │   ├── flying_item.gd
│   │   │   ├── flying_item.tscn
│   │   │   ├── game_speed_controller.gd
│   │   │   ├── game_speed_controller.tscn
│   │   │   ├── hud.gd
│   │   │   ├── hud.tscn
│   │   │   ├── label_with_rich_tooltip.gd
│   │   │   ├── mission_track_indicator.gd
│   │   │   ├── mission_track_indicator.tscn
│   │   │   ├── mission_tracker_container.gd
│   │   │   ├── mission_tracker_container.tscn
│   │   │   ├── movable_window.gd
│   │   │   ├── movable_window.tscn
│   │   │   ├── multiplayer_pause_indicator.tscn
│   │   │   ├── one_time_help_popup.gd
│   │   │   ├── rich_text_label_with_rich_tooltip.gd
│   │   │   ├── texture_rect_with_rich_tooltip.gd
│   │   │   ├── tutorial_menu.gd
│   │   │   └── tutorial_menu.tscn
│   │   ├── item_stash_menu/
│   │   │   ├── item_stash_menu.gd
│   │   │   └── item_stash_menu.tscn
│   │   ├── player_resource_display/
│   │   │   ├── player_resource_display.gd
│   │   │   ├── player_resource_display.tscn
│   │   │   ├── resource_status_panel.gd
│   │   │   └── resource_status_panel.tscn
│   │   ├── title_screen/
│   │   │   ├── configure_singleplayer_menu.gd
│   │   │   ├── configure_singleplayer_menu.tscn
│   │   │   ├── connecting_to_server_indicator.tscn
│   │   │   ├── encyclopedia_generic_tab.gd
│   │   │   ├── encyclopedia_generic_tab.tscn
│   │   │   ├── encyclopedia_items.gd
│   │   │   ├── encyclopedia_items.tscn
│   │   │   ├── encyclopedia_menu.gd
│   │   │   ├── encyclopedia_menu.tscn
│   │   │   ├── encyclopedia_towers.gd
│   │   │   ├── encyclopedia_towers.tscn
│   │   │   ├── export_exp_menu.gd
│   │   │   ├── export_exp_menu.tscn
│   │   │   ├── import_exp_menu.gd
│   │   │   ├── import_exp_menu.tscn
│   │   │   ├── lan_match/
│   │   │   │   ├── create_lan_match_menu.gd
│   │   │   │   ├── create_lan_match_menu.tscn
│   │   │   │   ├── lan_connect_menu.gd
│   │   │   │   ├── lan_connect_menu.tscn
│   │   │   │   ├── lan_lobby_menu.gd
│   │   │   │   ├── lan_lobby_menu.tscn
│   │   │   │   ├── setup_lan_game.gd
│   │   │   │   └── setup_lan_game.tscn
│   │   │   ├── match_config.gd
│   │   │   ├── match_config_panel.gd
│   │   │   ├── match_config_panel.tscn
│   │   │   ├── message_popup.gd
│   │   │   ├── message_popup.tscn
│   │   │   ├── missions_menu/
│   │   │   │   ├── mission_card.gd
│   │   │   │   ├── mission_card.tscn
│   │   │   │   ├── missions_menu.gd
│   │   │   │   ├── missions_menu.tscn
│   │   │   │   ├── missions_menu_tab.gd
│   │   │   │   └── missions_menu_tab.tscn
│   │   │   ├── notification_panel.gd
│   │   │   ├── notification_panel.tscn
│   │   │   ├── online/
│   │   │   │   ├── create_online_match_menu.gd
│   │   │   │   ├── create_online_match_menu.tscn
│   │   │   │   ├── match_card.gd
│   │   │   │   ├── match_card.tscn
│   │   │   │   ├── online_lobby_menu.gd
│   │   │   │   ├── online_lobby_menu.tscn
│   │   │   │   ├── online_match_list_menu.gd
│   │   │   │   ├── online_match_list_menu.tscn
│   │   │   │   ├── setup_online_game.gd
│   │   │   │   └── setup_online_game.tscn
│   │   │   ├── profile_menu.gd
│   │   │   ├── profile_menu.tscn
│   │   │   ├── title_screen.gd
│   │   │   ├── title_screen.tscn
│   │   │   ├── wisdom_upgrade_menu.gd
│   │   │   └── wisdom_upgrade_menu.tscn
│   │   ├── top_left_menu/
│   │   │   ├── game_stats.gd
│   │   │   ├── game_stats.tscn
│   │   │   ├── plus_mode_label.gd
│   │   │   ├── plus_mode_label.tscn
│   │   │   ├── top_left_menu.gd
│   │   │   ├── top_left_menu.tscn
│   │   │   ├── wave_status.gd
│   │   │   └── wave_status.tscn
│   │   ├── tower_stash_menu/
│   │   │   ├── tower_stash_menu.gd
│   │   │   └── tower_stash_menu.tscn
│   │   └── unit_menu/
│   │       ├── buff_container.gd
│   │       ├── buff_container.tscn
│   │       ├── buff_display.gd
│   │       ├── buff_display.tscn
│   │       ├── buff_group_editor.gd
│   │       ├── buff_group_editor.tscn
│   │       ├── creep_details.gd
│   │       ├── creep_details.tscn
│   │       ├── creep_mini_details.gd
│   │       ├── creep_mini_details.tscn
│   │       ├── item_container_panel.gd
│   │       ├── item_container_panel.tscn
│   │       ├── mini_details_label.tscn
│   │       ├── progress_bar_with_label.gd
│   │       ├── progress_bar_with_label.tscn
│   │       ├── tower_details.gd
│   │       ├── tower_details.tscn
│   │       ├── tower_mini_details.gd
│   │       ├── tower_mini_details.tscn
│   │       ├── unit_menu.gd
│   │       └── unit_menu.tscn
│   └── unit/
│       ├── dummy_unit.gd
│       ├── dummy_unit.tscn
│       ├── iterate.gd
│       ├── selection_indicator.gd
│       └── unit.gd
├── tools/
│   ├── README.md
│   ├── check_buff_icons.gd
│   ├── check_rng_sync.gd
│   ├── check_translations.gd
│   ├── check_tscn_paths_in_scripts.gd
│   ├── convert_blender_export.gd
│   ├── convert_tower_scene_to_sprite.gd
│   ├── create_tilesheet.gd
│   ├── cut_single_tile.gd
│   ├── cut_tiles_into_connectors.gd
│   ├── cut_tiles_into_decorations.gd
│   ├── generate_censored_assets.gd
│   ├── pack_sprite_sheet.gd
│   ├── remove_empty_space_tilesheet.gd
│   ├── remove_sheet_margins.gd
│   ├── rename_files.gd
│   ├── render_8_direction_sprites.py
│   ├── separate_tilesheet.gd
│   ├── show_missing_imports.py
│   └── slice_sheet_into_rows.gd
└── webrtc/
    └── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CODEOWNERS
================================================
*   @Kvel2D @Praytic


================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
  community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or advances of
  any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
  without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[INSERT CONTACT METHOD].
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series of
actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within the
community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].

[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contribution guidance

## How to contribute

You can contribute in different ways:

- Report a bug in Issues
- Write a suggestion in Discussions
- Submit a modification to source code!

For the last one, you will need to download the Godot editor and obtain assets.
Read below to find out how to obtain assets.

## Editing the game in the Godot editor

First, obtain necessary files:

1. Download Godot editor *version 4.3* from the [Godot website](https://godotengine.org).
2. Clone the game repository using Git.
3. Download assets folder from this [Google Drive folder](https://drive.google.com/drive/folders/1U4wTjBu2qo1cInH3IAowsFC5yq56V5uQ?usp=sharing).
4. Copy and paste downloaded assets into 'assets' folder in the game repository.
5. You will see a popup asking whether you want to replace some files - press "Yes".

Then, follow these steps to correctly import assets into Godot editor:

1. Open the game project in the Godot editor.
2. Wait for Godot editor to import assets. Open the "Output" window to confirm that the process is finished. There will be some errors - that's expected.
3. Press Ctrl-S to save changes.
4. Close Godot editor
5. Open a terminal with Git and run this command: $ git status. You should see that some files were modified (by Godot editor).
6. Run this command: $ git restore
7. Open the game project in the Godot editor again.
8. Wait for Godot editor to import assets. This time, there should be no errors.
9. Run this command again: $ git status. There should be no local changes if steps were followed correctly.

Note: Public version of assets contains censored versions of item icons, tower icons and tower sprites. Such assets will look like they are a solid "blue" color.

## Copyright / Contributor License Agreement
Any code you submit will become part of the repository and be distributed under the YouTD2 license. By submitting code to the project you agree that the code is your work and you can give it to the project.

You also agree by submitting your code that you grant all transferrable rights to the code to the project maintainer, including for example re-licensing the code, modifying the code, and distributing it in source or binary forms. Specifically, this includes a requirement that you assign copyright to the project maintainer. For this reason, do not modify any copyright statements in files in any PRs.


================================================
FILE: .github/RCLONE.md
================================================
# Setup rclone

Rclone is an advanced way to sync assets between your computer and google drive.

Note that if you're using the public version of assets (assets_public), you can ignore this page and manually download files from drive.

## Setup steps

1. Install rclone from [here](https://rclone.org/downloads/).
2. Go to this [page](https://console.cloud.google.com/apis/credentials/oauthclient/909699965518-qt5c21qf6r7mr3rg26vkh6nml4s397e7.apps.googleusercontent.com?project=youtd2-385722). Copy and save `client_id` and `client_secret` to a text file. You will need them in the next step.
3. Follow the instructions [here](https://rclone.org/drive/) to configure `rcloud`. When prompted for `client_id` and `client_secret`, use the strings you have copied in the previous step.
4. Check that the remote is installed correctly. This command will print the installed `<remote>`.
```
rclone listremotes
```
5. This command should print the list of folders insides assets in Google Drive.
```
rclone lsd <remote>:assets
```
6. Transfer files to your local.
```
rclone sync -P --filter-from rclone-filter "<remote>:assets" "assets"
```

Now you should be able to run the project inside the Godot editor. If you make changes to a file inside assets folder, make sure to update Google Drive as well. There are two options.

**First option - Google Drive upload.**

1. Upload a file to [Google Drive](https://drive.google.com/drive/u/1/folders/1V9GN1uoX9-mu2J5IoWPaNJU2aC_ejGIA)
2. Run `rclone sync`
3. Generate `.import` by opening the file in the editor
4. Commit `.import` file to remote

**Second option - rclone copy.**
1. Move a file to `assets` folder
2. Generate `.import` by opening the file in the editor
3. Commit `.import` file to remote
4. Upload the file to <remote>.
```
rclone copy -v --filter-from rclone-filter assets <remote>:assets
```


================================================
FILE: .github/TRANSLATING.md
================================================
# Translation guidance

## How to contribute to translation

Translated text strings are stored in texts.csv. This file is not included on Github because it is too big.
Download link: [texts.csv](https://drive.google.com/file/d/1dfaUKx5CoU9oVQQ4DgFVJH_twJ7M5k4Q/view?usp=drive_link).

You can contribute translations like this:
1. Download the texts.csv file
2. Edit the texts.csv file
3. Create new column for your language, for example "es"
4. Add translated strings to that column

Then you can submit the changes like this:
1. Create a new Issue on Github
2. Attach changed texts.csv file to the Issue
3. Follow the format from here: https://github.com/Praytic/youtd2/issues/483

## How to add a new language

This section is intended for developers. If you only want to contribute new translation texts, you can skip this section and let someone else handle adding the new language.

1. Find the locale code here: https://docs.godotengine.org/en/stable/tutorials/i18n/locales.html
2. Create new column in texts.csv with locale code in first row.
3. Close texts.csv and open Godot editor, confirm in editor log that texts.csv was reloaded.
4. Go to Menubar -> Project -> Project Settings -> Localization -> Add. Then add the translation file.
5. Edit src/enums/language.gd. Add new language to the following: "enm", "language_map", "language_option_map", "language_option_locale_map"
6. Open settings_menu.tscn in editor and modify the language OptionButton. Add new language and use the same index as the one in language.gd.
7. Start the game and confirm that new language works.


================================================
FILE: .github/workflows/github-actions-youtd.yml
================================================
name: build-and-publish

# NOTE: disabled this export job because it doesn't work
# with webrtc lib. Webrtc lib files need to be included
# together with the game but this job for some reason fails
# to do it. It only adds executable and .pck file to the
# zip.

# on:
#   push:
#     # Sequence of patterns matched against refs/heads
#     # branches:
#     #   - workflow*
#     # Sequence of patterns matched against refs/tags
#     tags:
#       - v*

jobs:
  setup:
    runs-on: ubuntu-latest
    name: cache repo with assets
    steps:
    - uses: actions/checkout@v3

    - name: list assets in gdrive
      uses: wei/rclone@v1
      with:
        args: lsf -R --filter-from rclone-filter "assets" | sort > .assets-list
      env:
        RCLONE_CONF: ${{ secrets.RCLONE_GDRIVE_CONF }}

    - name: restore cache
      uses: actions/cache@v3
      with:
        path: assets
        key: assets-${{ hashFiles('.assets-list') }}

    - name: sync assets from gdrive via rclone
      uses: wei/rclone@v1
      with:
        args: sync -P --filter-from rclone-filter "gdrive:assets" "assets"
      env:
        RCLONE_CONF: ${{ secrets.RCLONE_GDRIVE_CONF }}

    - name: upload repo with assets
      id: upload_repo_with_assets
      uses: actions/upload-artifact@v3
      with:
        path: |
          ./*
          !.git/
        name: repo-with-assets

    - name: generate version for the build
      id: version_generation
      run: |
        latest_tag=$(git ls-remote --tags --sort=-v:refname origin | grep -v 'vrefs/heads/main' | grep -o 'refs/tags/[^^{]*' | sed 's/refs\/tags\///' | head -n 1)
        short_hash=$(git rev-parse --short HEAD)
        version=${latest_tag:1}
        echo "tag_version=${latest_tag}-${short_hash}" | tee -a $GITHUB_OUTPUT
        echo "version=${version}" | tee -a $GITHUB_OUTPUT
        echo "commit_ref=$GITHUB_REF_NAME" | tee -a $GITHUB_OUTPUT

    outputs:
      tag_version: ${{ steps.version_generation.outputs.tag_version }}
      version: ${{ steps.version_generation.outputs.version }}
      commit_ref: ${{ steps.version_generation.outputs.commit_ref }}

  export_game:
    runs-on: ubuntu-latest
    needs: setup
    name: export game
    steps:
    - name: download repo with assets
      uses: actions/download-artifact@v3
      with:
        path: ./
        name: repo-with-assets

    - name: release requested check
      run: |
        if [[ ${{ needs.setup.outputs.commit_ref }} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] ; then
            echo "NEED=true" >> "$GITHUB_ENV"
            echo 'true'
        else
            echo "NEED=false" >> "$GITHUB_ENV"
            echo 'false'
        fi

    - name: update project.godot with new version
      run: |
        project_godot_file="${{ github.workspace }}/project.godot"
        sed -i 's/\(config\/version="\).*\("\)/\1'"${{ needs.setup.outputs.tag_version }}"'\2/' "${project_godot_file}"
        echo "New project.godot contents:"
        cat "${project_godot_file}"

    - name: update release version for Sentry lib
      run: |
        sed -i "s/youtd2@[0-9]\+\.[0-9]\+\.[0-9]\+/youtd2@${{ needs.setup.outputs.version }}/g" "${{ github.workspace }}/build/web/full-size.html"

    - name: create .godot dirs
      run: |
        mkdir -p .godot/{editor,imported}

    - name: export game
      id: export
      uses: firebelley/godot-export@v5.2.0
      with:
        godot_executable_download_url: https://github.com/godotengine/godot-builds/releases/download/4.1.3-stable/Godot_v4.1.3-stable_linux.x86_64.zip
        godot_export_templates_download_url: https://github.com/godotengine/godot-builds/releases/download/4.1.3-stable/Godot_v4.1.3-stable_export_templates.tpz
        relative_project_path: ./
        export_debug: false
        archive_output: true
        cache: true
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: repack web artifact
      run: |
        zip -uj ${{ steps.export.outputs.archive_directory }}/web.zip ${{ github.workspace }}/build/web/*
        cp ${{ github.workspace }}/build/web/* ${{ steps.export.outputs.build_directory }}/web/

    - uses: actions/upload-artifact@v3
      with:
        name: youtd-${{ needs.setup.outputs.tag_version }}
        path: ${{ steps.export.outputs.archive_directory }}/*.zip
        if-no-files-found: error

    outputs:
      tag_version: ${{ needs.setup.outputs.tag_version }}
      commit_ref: ${{ needs.setup.outputs.commit_ref }}
      release_flag: ${{ env.NEED }}

  upload_artifacts:
    needs: export_game
    strategy:
      matrix:
        platform: [windows, macos, web, linux]
    runs-on: ubuntu-latest
    steps:
    - name: download exported files
      uses: actions/download-artifact@v3
      with:
        name: youtd-${{ needs.export_game.outputs.tag_version }}
        path: exported_files

    - name: rename artifacts
      id: rename_artifacts
      run: |
        VERSION_TAG="${{ needs.export_game.outputs.tag_version }}"
        mv "exported_files/${{ matrix.platform }}.zip" "exported_files/${{ matrix.platform }}-$VERSION_TAG.zip"
        echo "${{ matrix.platform }}=exported_files/$platform-$VERSION_TAG.zip" >> $GITHUB_OUTPUT

    - name: upload artifacts
      id: upload_artifacts
      uses: actions/upload-artifact@v3
      with:
        name: ${{ matrix.platform }}-${{ needs.export_game.outputs.tag_version }}
        path: exported_files/${{ matrix.platform }}-${{ needs.export_game.outputs.tag_version }}.zip

    outputs:
      macos_artifact: ${{ steps.rename_artifacts.outputs.macos_artifact }}
      linux_artifact: ${{ steps.rename_artifacts.outputs.linux_artifact }}
      web_artifact: ${{ steps.rename_artifacts.outputs.web_artifact }}
      windows_artifact: ${{ steps.rename_artifacts.outputs.windows_artifact }}

  create_release:
    name: create release
    needs: [upload_artifacts, export_game]
    if: needs.export_game.outputs.release_flag == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: show props
        run: |
          echo "Commit ref: $GITHUB_REF_NAME"
          echo "Release tag: ${{ needs.export_game.outputs.commit_ref }}"

      - name: download artifacts
        uses: actions/download-artifact@v3
        with:
          path: .

      - name: display structure of downloaded files
        run: ls -R
        working-directory: .

      - name: release client
        uses: ncipollo/release-action@v1.11.2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ needs.export_game.outputs.commit_ref }}
          generateReleaseNotes: true
          artifacts: ./**/*.zip

  clean_up_artifacts:
    needs: [create_release, export_game]
    runs-on: ubuntu-latest
    steps:
      - uses: geekyeggo/delete-artifact@v2
        with:
          name: |
            youtd-${{ needs.export_game.outputs.tag_version }}
            repo-with-assets


================================================
FILE: .gitignore
================================================
# Godot .gitignore config
#
# Aims to encompass the most commonly found files that we don't want committed
# to Git, such as compilation output, IDE specific files, etc.
#
# It doesn't cover *all* thirdparty IDE extensions under the sun so if you have
# specific needs covered here, you can add them to:
#   .git/info/exclude
#
# Or contribute them to this file if they're common enough that a good number of
# users would benefit from the shared rules.
#
# This file is organized by sections, with subsections ordered alphabetically.
# - Build configuration
# - Godot generated files
# - General build output
# - IDE and tool specific
# - Visual Studio specific
# - OS specific

###########################
### Build configuration ###
###########################

/custom.py
misc/hooks/pre-commit-custom-*

#############################
### Godot generated files ###
#############################

# Buildsystem
bin/
*.gen.*
compile_commands.json
platform/windows/godot_res.res

# Generated by Godot binary
.import/
.godot/
/gdnative_interface.h
extension_api.json
logs/
*.translation

# Generated by unit tests
tests/data/*.translation

############################
### General build output ###
############################

# C/C++ generated
*.a
*.ax
*.d
*.dll
*.lib
*.lo
*.o
*.os
*.ox
*.Plo
*.so
# Binutils tmp linker output of the form "stXXXXXX" where "X" is alphanumeric
st[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]

# Python generated
__pycache__/
*.pyc

# Documentation
doc/_build/

# Android
.gradle/
local.properties
*.iml
.gradletasknamecache
project.properties
platform/android/java/*/.cxx/
platform/android/java/*/build/
platform/android/java/*/libs/

# iOS
*.dSYM

# Web platform
*.bc
platform/web/node_modules/

# Misc
*.debug

#############################
### IDE and tool specific ###
#############################

# Automake
.deps/*
.dirstamp

# ccls
.ccls-cache/

# clangd
.clangd/
.cache/

# CLion
cmake-build-debug

# Code::Blocks
*.cbp
*.layout
*.depend

# CodeLite
*.project
*.workspace
.codelite/

# Cppcheck
*.cppcheck
cppcheck-cppcheck-build-dir/

# Eclipse CDT
.cproject
.settings/
*.pydevproject
*.launch

# Gcov and Lcov code coverage
*.gcno
*.gcda
*.gcov.html
*.func.html
*.func-sort-c.html
*index-sort-f.html
*index-sort-l.html
*index.html
godot.info
amber.png
emerald.png
glass.png
ruby.png
snow.png
updown.png
gcov.css

# Geany
*.geany
.geanyprj

# Gprof
gmon.out

# Jetbrains IDEs
.idea/
.fleet/

# Kate
*.kate-swp

# Kdevelop
*.kdev4

# Qt Creator
*.config
*.creator
*.creator.*
*.files
*.includes
*.cflags
*.cxxflags

# SCons
.sconf_temp
.sconsign*.dblite
.scons_env.json
.scons_node_count

# Sourcetrail
*.srctrl*

# Tags
# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
TAGS
!TAGS/
tags
*.tags
!tags/
gtags.files
GTAGS
GRTAGS
GPATH
cscope.files
cscope.out
cscope.in.out
cscope.po.out

# Vim
*.swo
*.swp

# Visual Studio Code
.vscode/
*.code-workspace
.history/

# Xcode
xcuserdata/
*.xcscmblueprint
*.xccheckout
*.xcodeproj/*

##############################
### Visual Studio specific ###
##############################

# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# Ignore Visual Studio temporary files, build results, and
# files generated by popular Visual Studio add-ons.

# Actual VS project files we don't use
*.sln
*.vcxproj*

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# Visual Studio 2015/2017 cache/options directory
.vs/

# Visual Studio 2017 auto generated files
Generated\ Files/

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache

# Others
ClientBin/
enc_temp_folder/
~$*
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# Hint file for IntelliSense
cpp.hint

###################
### OS specific ###
###################

# Linux
*~
.directory

# macOS
.DS_Store
__MACOSX

# Windows
# https://github.com/github/gitignore/blob/main/Global/Windows.gitignore
[Tt]humbs.db
[Tt]humbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
*.stackdump
[Dd]esktop.ini
$RECYCLE.BIN/
*.cab
*.msi
*.msix
*.msm
*.msp
*.lnk


########################
### Project specific ###
########################

/build/windows/YouTD2.zip
/build/linux/YouTD2.zip
/build/macos/YouTD2.zip
/build/web/*
!/build/README.md
!/build/web/full-size.html
!/build/web/loading_screen.mp4
!/build/web/loading_screen.png
override.cfg
/webrtc/*
!/webrtc/README.md

#######################
### Assets specific ###
#######################

# Archives
*.7z
*.br
*.gz
*.tar
*.zip

# Documents
*.pdf

# Images
*.gif
*.ico
*.jpg
*.png
*.psd
*.webp

# Fonts
*.woff2
*.otf
*.ttf

# Audio
*.mp3
*.wav
*.ogg

# Other
*.exe
/assets/secrets/secrets.csv
/assets/secrets/badwords.csv
/assets/texts/texts.csv


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2023 Icob2Games

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# YouTD 2

![youtd2_logo](https://github.com/user-attachments/assets/ea8a358b-aa12-4d28-9fc5-861bf8d2c497)

YouTD 2 is a remake of the tower defense mod "YouTD" from WC3.

_[itch.io](https://praytic.itch.io/youtd2)_  
_[Discord](https://discord.gg/EksA2CfCS9)_  

## Contributing
See [CONTRIBUTING.md](.github/CONTRIBUTING.md).

## Matchmaking server

Repository for matchmaking server is [here](https://github.com/Kvel2D/youtd2-server).

## Credits

Developed by [Dmitry Degtyarev](https://github.com/Kvel2D), [Praytic](https://github.com/Praytic) and every direct and indirect [contributors](https://github.com/Praytic/youtd2/graphs/contributors) to the GitHub.

Based on "YouTD" - a WC3 mod created by geX and the YouTD community.

Also thank you to everyone posting feedback and questions on YouTD2 Discord.

## License

YouTD 2 source code is licensed under the [MIT licence](https://github.com/Praytic/youtd2/tree/main?tab=MIT-1-ov-file#readme).

Assets files are licensed under [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/legalcode).


================================================
FILE: addons/com.heroiclabs.nakama/Nakama.gd
================================================
@tool
extends Node

# The default host address of the server.
const DEFAULT_HOST : String = "127.0.0.1"

# The default port number of the server.
const DEFAULT_PORT : int = 7350

# The default timeout for the connections.
const DEFAULT_TIMEOUT = 3

# The default protocol scheme for the client connection.
const DEFAULT_CLIENT_SCHEME : String = "http"

# The default protocol scheme for the socket connection.
const DEFAULT_SOCKET_SCHEME : String = "ws"

# The default log level for the Nakama logger.
const DEFAULT_LOG_LEVEL = NakamaLogger.LOG_LEVEL.DEBUG

var _http_adapter = null
var logger = NakamaLogger.new()

func _ready() -> void:
	process_mode = Node.PROCESS_MODE_ALWAYS

func get_client_adapter() -> NakamaHTTPAdapter:
	if _http_adapter == null:
		_http_adapter = NakamaHTTPAdapter.new()
		_http_adapter.logger = logger
		_http_adapter.name = "NakamaHTTPAdapter"
		add_child(_http_adapter)
	return _http_adapter

func create_socket_adapter() -> NakamaSocketAdapter:
	var adapter = NakamaSocketAdapter.new()
	adapter.name = "NakamaWebSocketAdapter"
	adapter.logger = logger
	add_child(adapter)
	return adapter

func create_client(p_server_key : String,
		p_host : String = DEFAULT_HOST,
		p_port : int = DEFAULT_PORT,
		p_scheme : String = DEFAULT_CLIENT_SCHEME,
		p_timeout : int = DEFAULT_TIMEOUT,
		p_log_level : int = DEFAULT_LOG_LEVEL) -> NakamaClient:
	logger._level = p_log_level
	return NakamaClient.new(get_client_adapter(), p_server_key, p_scheme, p_host, p_port, p_timeout)

func create_socket(p_host : String = DEFAULT_HOST,
		p_port : int = DEFAULT_PORT,
		p_scheme : String = DEFAULT_SOCKET_SCHEME) -> NakamaSocket:
	return NakamaSocket.new(create_socket_adapter(), p_host, p_port, p_scheme, true)

func create_socket_from(p_client : NakamaClient) -> NakamaSocket:
	var scheme = "ws"
	if p_client.scheme == "https":
		scheme = "wss"
	return NakamaSocket.new(create_socket_adapter(), p_client.host, p_client.port, scheme, true)


================================================
FILE: addons/com.heroiclabs.nakama/Satori/NakamaEvent.gd
================================================
extends SatoriAsyncResult

# NOTE: renamed from original "Event" to avoid name conflicts
class_name NakamaEvent

# The name of the event.
var name: String

# The time when the event was triggered.
var timestamp: String

# Optional value.
var value: String

# NakamaEvent metadata, if any.
var metadata: Dictionary

# Optional event ID assigned by the client, used to de-duplicate in retransmission scenarios.
# If not supplied the server will assign a randomly generated unique event identifier.
var id: String

# The event constructor.
 # Initializes a new NakamaEvent object.
 #
 # @param name The name of the event.
 # @param timestamp The timestamp of the event.
 # @param value The value associated with the event (optional).
 # @param metadata The metadata associated with the event (optional).
 # @param id The ID of the event (optional).
func _init(name: String, timestamp: float, value: String = "", metadata: Dictionary = {}, id: String = "", p_exception = null):
	super(p_exception)
	
	self.name = name
	self.timestamp = unix_to_protobuf_timestamp_format(timestamp)
	self.value = value
	self.metadata = metadata
	self.id = id

func to_api_event_dict() -> Dictionary:
	return {
		"name": self.name,
		"timestamp": self.timestamp,
		"value": self.value,
		"metadata": self.metadata,
		"id": self.id
	}

func unix_to_protobuf_timestamp_format(unix_time: float) -> String:
	# Extract microseconds precision from unix time
	var microseconds = int(fmod(unix_time, 1.0) * 1_000_000)
	
	# Convert seconds to datetime structure
	var datetime = Time.get_datetime_dict_from_unix_time(int(unix_time))
	
	var year = datetime.year
	var month = str(datetime.month).pad_zeros(2)
	var day = str(datetime.day).pad_zeros(2)
	var hour = str(datetime.hour).pad_zeros(2)
	var minute = str(datetime.minute).pad_zeros(2)
	var second = str(datetime.second).pad_zeros(2)
	var microsecond = str(microseconds).pad_zeros(6)

	# Construct the protobuf timestamp format string
	var timestamp_str = "%s-%s-%sT%s:%s:%s.%sZ" % [year, month, day, hour, minute, second, microsecond]
	
	return timestamp_str


================================================
FILE: addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd
================================================
### Code generated by codegen/main.go. DO NOT EDIT. ###

extends RefCounted
class_name SatoriAPI

# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
class ApiAuthenticateLogoutRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}
	
	# Refresh token to invalidate.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)
	
	# Session token to log out.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateLogoutRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateLogoutRequest", p_dict), ApiAuthenticateLogoutRequest) as ApiAuthenticateLogoutRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		output += map_string
		return output

# Authenticate against the server with a refresh token.
class ApiAuthenticateRefreshRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
	}
	
	# Refresh token.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRefreshRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRefreshRequest", p_dict), ApiAuthenticateRefreshRequest) as ApiAuthenticateRefreshRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "refresh_token: %s, " % _refresh_token
		output += map_string
		return output

# 
class ApiAuthenticateRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
	}
	
	# Optional custom properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Optional default properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Identity ID. Must be between eight and 128 characters (inclusive).
	# Must be an alphanumeric string with only underscores and hyphens allowed.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRequest", p_dict), ApiAuthenticateRequest) as ApiAuthenticateRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "id: %s, " % _id
		output += map_string
		return output

# A single event. Usually, but not necessarily, part of a batch.
class ApiEvent extends SatoriAsyncResult:

	const _SCHEMA = {
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# Optional event ID assigned by the client, used to de-duplicate in retransmission scenarios.
	# If not supplied the server will assign a randomly generated unique event identifier.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)
	
	# Event metadata, if any.
	var _metadata
	var metadata : Dictionary:
		get:
			return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
	
	# Event name.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# The time when the event was triggered on the producer side.
	var _timestamp
	var timestamp : String:
		get:
			return "" if not _timestamp is String else String(_timestamp)
	
	# Optional value.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "id: %s, " % _id
		if typeof(_metadata) == TYPE_DICTIONARY:
			for k in _metadata:
				map_string += "{%s=%s}, " % [k, _metadata[k]]
		output += "metadata: [%s], " % map_string
		map_string = ""
		output += "name: %s, " % _name
		output += "timestamp: %s, " % _timestamp
		output += "value: %s, " % _value
		output += map_string
		return output

# 
class ApiEventRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"events": {"name": "_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# Some number of events produced by a client.
	var _events
	var events : Array:
		get:
			return Array() if not _events is Array else Array(_events)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEventRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEventRequest", p_dict), ApiEventRequest) as ApiEventRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "events: %s, " % [_events]
		output += map_string
		return output

# An experiment that this user is partaking.
class ApiExperiment extends SatoriAsyncResult:

	const _SCHEMA = {
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Value associated with this Experiment.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperiment:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperiment", p_dict), ApiExperiment) as ApiExperiment

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# All experiments that this identity is involved with.
class ApiExperimentList extends SatoriAsyncResult:

	const _SCHEMA = {
		"experiments": {"name": "_experiments", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# All experiments for this identity.
	var _experiments
	var experiments : Array:
		get:
			return Array() if not _experiments is Array else Array(_experiments)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperimentList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperimentList", p_dict), ApiExperimentList) as ApiExperimentList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "experiments: %s, " % [_experiments]
		output += map_string
		return output

# Feature flag available to the identity.
class ApiFlag extends SatoriAsyncResult:

	const _SCHEMA = {
		"condition_changed": {"name": "_condition_changed", "type": TYPE_BOOL, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# Whether the value for this flag has conditionally changed from the default state.
	var _condition_changed
	var condition_changed : bool:
		get:
			return false if not _condition_changed is bool else bool(_condition_changed)
	
	# 
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Value associated with this flag.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlag:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlag", p_dict), ApiFlag) as ApiFlag

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "condition_changed: %s, " % _condition_changed
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# 
class ApiFlagList extends SatoriAsyncResult:

	const _SCHEMA = {
		"flags": {"name": "_flags", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# 
	var _flags
	var flags : Array:
		get:
			return Array() if not _flags is Array else Array(_flags)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlagList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlagList", p_dict), ApiFlagList) as ApiFlagList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "flags: %s, " % [_flags]
		output += map_string
		return output

# A response containing all the messages for an identity.
class ApiGetMessageListResponse extends SatoriAsyncResult:

	const _SCHEMA = {
		"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
		"messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
		"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
	}
	
	# Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
	var _cacheable_cursor
	var cacheable_cursor : String:
		get:
			return "" if not _cacheable_cursor is String else String(_cacheable_cursor)
	
	# The list of messages.
	var _messages
	var messages : Array:
		get:
			return Array() if not _messages is Array else Array(_messages)
	
	# The cursor to send when retrieving the next page, if any.
	var _next_cursor
	var next_cursor : String:
		get:
			return "" if not _next_cursor is String else String(_next_cursor)
	
	# The cursor to send when retrieving the previous page, if any.
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGetMessageListResponse:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiGetMessageListResponse", p_dict), ApiGetMessageListResponse) as ApiGetMessageListResponse

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "cacheable_cursor: %s, " % _cacheable_cursor
		output += "messages: %s, " % [_messages]
		output += "next_cursor: %s, " % _next_cursor
		output += "prev_cursor: %s, " % _prev_cursor
		output += map_string
		return output

# Enrich/replace the current session with a new ID.
class ApiIdentifyRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
	}
	
	# Optional custom properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Optional default properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Identity ID to enrich the current session and return a new session. Old session will no longer be usable.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiIdentifyRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiIdentifyRequest", p_dict), ApiIdentifyRequest) as ApiIdentifyRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "id: %s, " % _id
		output += map_string
		return output

# A single live event.
class ApiLiveEvent extends SatoriAsyncResult:

	const _SCHEMA = {
		"active_end_time_sec": {"name": "_active_end_time_sec", "type": TYPE_STRING, "required": false},
		"active_start_time_sec": {"name": "_active_start_time_sec", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# End time of current event run.
	var _active_end_time_sec
	var active_end_time_sec : String:
		get:
			return "" if not _active_end_time_sec is String else String(_active_end_time_sec)
	
	# Start time of current event run.
	var _active_start_time_sec
	var active_start_time_sec : String:
		get:
			return "" if not _active_start_time_sec is String else String(_active_start_time_sec)
	
	# Description.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)
	
	# The live event identifier.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)
	
	# Name.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Event value.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEvent:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEvent", p_dict), ApiLiveEvent) as ApiLiveEvent

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "active_end_time_sec: %s, " % _active_end_time_sec
		output += "active_start_time_sec: %s, " % _active_start_time_sec
		output += "description: %s, " % _description
		output += "id: %s, " % _id
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# List of Live events.
class ApiLiveEventList extends SatoriAsyncResult:

	const _SCHEMA = {
		"live_events": {"name": "_live_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# Live events.
	var _live_events
	var live_events : Array:
		get:
			return Array() if not _live_events is Array else Array(_live_events)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEventList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEventList", p_dict), ApiLiveEventList) as ApiLiveEventList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "live_events: %s, " % [_live_events]
		output += map_string
		return output

# A scheduled message.
class ApiMessage extends SatoriAsyncResult:

	const _SCHEMA = {
		"consume_time": {"name": "_consume_time", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"read_time": {"name": "_read_time", "type": TYPE_STRING, "required": false},
		"schedule_id": {"name": "_schedule_id", "type": TYPE_STRING, "required": false},
		"send_time": {"name": "_send_time", "type": TYPE_STRING, "required": false},
		"text": {"name": "_text", "type": TYPE_STRING, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
	}
	
	# The time the message was consumed by the identity.
	var _consume_time
	var consume_time : String:
		get:
			return "" if not _consume_time is String else String(_consume_time)
	
	# The time the message was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)
	
	# A key-value pairs of metadata.
	var _metadata
	var metadata : Dictionary:
		get:
			return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
	
	# The time the message was read by the client.
	var _read_time
	var read_time : String:
		get:
			return "" if not _read_time is String else String(_read_time)
	
	# The identifier of the schedule.
	var _schedule_id
	var schedule_id : String:
		get:
			return "" if not _schedule_id is String else String(_schedule_id)
	
	# The send time for the message.
	var _send_time
	var send_time : String:
		get:
			return "" if not _send_time is String else String(_send_time)
	
	# The message's text.
	var _text
	var text : String:
		get:
			return "" if not _text is String else String(_text)
	
	# The time the message was updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMessage:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiMessage", p_dict), ApiMessage) as ApiMessage

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "consume_time: %s, " % _consume_time
		output += "create_time: %s, " % _create_time
		if typeof(_metadata) == TYPE_DICTIONARY:
			for k in _metadata:
				map_string += "{%s=%s}, " % [k, _metadata[k]]
		output += "metadata: [%s], " % map_string
		map_string = ""
		output += "read_time: %s, " % _read_time
		output += "schedule_id: %s, " % _schedule_id
		output += "send_time: %s, " % _send_time
		output += "text: %s, " % _text
		output += "update_time: %s, " % _update_time
		output += map_string
		return output

# Properties associated with an identity.
class ApiProperties extends SatoriAsyncResult:

	const _SCHEMA = {
		"computed": {"name": "_computed", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}
	
	# Event computed properties.
	var _computed
	var computed : Dictionary:
		get:
			return Dictionary() if not _computed is Dictionary else _computed.duplicate()
	
	# Event custom properties.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Event default properties.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiProperties:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiProperties", p_dict), ApiProperties) as ApiProperties

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_computed) == TYPE_DICTIONARY:
			for k in _computed:
				map_string += "{%s=%s}, " % [k, _computed[k]]
		output += "computed: [%s], " % map_string
		map_string = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += map_string
		return output

# A session.
class ApiSession extends SatoriAsyncResult:

	const _SCHEMA = {
		"properties": {"name": "_properties", "type": "ApiProperties", "required": false},
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}
	
	# Properties associated with this identity.
	var _properties
	var properties : ApiProperties:
		get:
			return _properties as ApiProperties
	
	# Refresh token.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)
	
	# Token credential.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "properties: %s, " % _properties
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		output += map_string
		return output

# Update Properties associated with this identity.
class ApiUpdatePropertiesRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"recompute": {"name": "_recompute", "type": TYPE_BOOL, "required": false},
	}
	
	# Event custom properties.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Event default properties.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Informs the server to recompute the audience membership of the identity.
	var _recompute
	var recompute : bool:
		get:
			return false if not _recompute is bool else bool(_recompute)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdatePropertiesRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiUpdatePropertiesRequest", p_dict), ApiUpdatePropertiesRequest) as ApiUpdatePropertiesRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "recompute: %s, " % _recompute
		output += map_string
		return output

# 
class ProtobufAny extends SatoriAsyncResult:

	const _SCHEMA = {
		"type": {"name": "_type", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _type
	var type : String:
		get:
			return "" if not _type is String else String(_type)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ProtobufAny:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ProtobufAny", p_dict), ProtobufAny) as ProtobufAny

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "type: %s, " % _type
		output += map_string
		return output

# 
class RpcStatus extends SatoriAsyncResult:

	const _SCHEMA = {
		"code": {"name": "_code", "type": TYPE_INT, "required": false},
		"details": {"name": "_details", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
		"message": {"name": "_message", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _code
	var code : int:
		get:
			return 0 if not _code is int else int(_code)
	
	# 
	var _details
	var details : Array:
		get:
			return Array() if not _details is Array else Array(_details)
	
	# 
	var _message
	var message : String:
		get:
			return "" if not _message is String else String(_message)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> RpcStatus:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "RpcStatus", p_dict), RpcStatus) as RpcStatus

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "code: %s, " % _code
		output += "details: %s, " % [_details]
		output += "message: %s, " % _message
		output += map_string
		return output

# The low level client for the Satori API.
class ApiClient extends RefCounted:

	var _base_uri : String

	var _http_adapter
	var _namespace : GDScript
	var _server_key : String
	var auto_refresh := true
	var auto_refresh_time := 300

	var auto_retry : bool:
		set(p_value):
			_http_adapter.auto_retry = p_value
		get:
			return _http_adapter.auto_retry

	var auto_retry_count : int:
		set(p_value):
			_http_adapter.auto_retry_count = p_value
		get:
			return _http_adapter.auto_retry_count

	var auto_retry_backoff_base : int:
		set(p_value):
			_http_adapter.auto_retry_backoff_base = p_value
		get:
			return _http_adapter.auto_retry_backoff_base

	var last_cancel_token:
		get:
			return _http_adapter.get_last_token()

	func _init(p_base_uri : String, p_http_adapter, p_namespace : GDScript, p_server_key : String, p_timeout : int = 10):
		_base_uri = p_base_uri
		_http_adapter = p_http_adapter
		_http_adapter.timeout = p_timeout
		_namespace = p_namespace
		_server_key = p_server_key

		
	func _refresh_session(p_session : SatoriSession):
		if auto_refresh and p_session.is_valid() and p_session.refresh_token and not p_session.is_refresh_expired() and p_session.would_expire_in(auto_refresh_time):
			var request = ApiAuthenticateRefreshRequest.new()
			request._token = p_session.refresh_token
			return await authenticate_refresh_async(_server_key, "", request)
		return null

	func cancel_request(p_token):
		if p_token:
			_http_adapter.cancel_request(p_token)

	# A healthcheck which load balancers can use to check the service.
	func healthcheck_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/healthcheck"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# A readycheck which load balancers can use to check the service.
	func readycheck_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/readycheck"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Authenticate against the server.
	func authenticate_async(
		p_basic_auth_username : String
		, p_basic_auth_password : String
		, p_body : ApiAuthenticateRequest
	) -> ApiSession:
		var urlpath : String = "/v1/authenticate"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
		var header = "Basic %s" % credentials
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
	func authenticate_logout_async(
		p_session : SatoriSession
		, p_body : ApiAuthenticateLogoutRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/authenticate/logout"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Refresh a user's session using a refresh token retrieved from a previous authentication request.
	func authenticate_refresh_async(
		p_basic_auth_username : String
		, p_basic_auth_password : String
		, p_body : ApiAuthenticateRefreshRequest
	) -> ApiSession:
		var urlpath : String = "/v1/authenticate/refresh"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
		var header = "Basic %s" % credentials
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Publish an event for this session.
	func event_async(
		p_session : SatoriSession
		, p_body : ApiEventRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/event"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Get or list all available experiments for this identity.
	func get_experiments_async(
		p_session : SatoriSession
		, p_names = null # : array
	) -> ApiExperimentList:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiExperimentList.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/experiment"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiExperimentList.new(result)
		var out : ApiExperimentList = SatoriSerializer.deserialize(_namespace, "ApiExperimentList", result)
		return out

	# List all available flags for this identity.
	func get_flags_async(
		p_bearer_token : String
		, p_names = null # : array
	) -> ApiFlagList:
		var urlpath : String = "/v1/flag"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		if (p_bearer_token):
			var header = "Bearer %s" % p_bearer_token
			headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiFlagList.new(result)
		var out : ApiFlagList = SatoriSerializer.deserialize(_namespace, "ApiFlagList", result)
		return out

	# Enrich/replace the current session with new identifier.
	func identify_async(
		p_session : SatoriSession
		, p_body : ApiIdentifyRequest
	) -> ApiSession:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiSession.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/identify"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Delete the caller's identity and associated data.
	func delete_identity_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/identity"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "DELETE"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# List available live events.
	func get_live_events_async(
		p_session : SatoriSession
		, p_names = null # : array
	) -> ApiLiveEventList:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiLiveEventList.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/live-event"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiLiveEventList.new(result)
		var out : ApiLiveEventList = SatoriSerializer.deserialize(_namespace, "ApiLiveEventList", result)
		return out

	# Get the list of messages for the identity.
	func get_message_list_async(
		p_session : SatoriSession
		, p_limit = null # : integer
		, p_forward = null # : boolean
		, p_cursor = null # : string
	) -> ApiGetMessageListResponse:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiGetMessageListResponse.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message"
		var query_params = ""
		if p_limit != null:
			query_params += "limit=%d&" % p_limit
		if p_forward != null:
			query_params += "forward=%s&" % str(bool(p_forward)).to_lower()
		if p_cursor != null:
			query_params += "cursor=%s&" % SatoriSerializer.escape_http(p_cursor)
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiGetMessageListResponse.new(result)
		var out : ApiGetMessageListResponse = SatoriSerializer.deserialize(_namespace, "ApiGetMessageListResponse", result)
		return out

	# Deletes a message for an identity.
	func delete_message_async(
		p_session : SatoriSession
		, p_id : String
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message/{id}"
		urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "DELETE"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Updates a message for an identity.
	func update_message_async(
		p_session : SatoriSession
		, p_id : String
		, p_body : 
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message/{id}"
		urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# List properties associated with this identity.
	func list_properties_async(
		p_session : SatoriSession
	) -> ApiProperties:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiProperties.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/properties"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiProperties.new(result)
		var out : ApiProperties = SatoriSerializer.deserialize(_namespace, "ApiProperties", result)
		return out

	# Update identity properties.
	func update_properties_async(
		p_session : SatoriSession
		, p_body : ApiUpdatePropertiesRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/properties"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()


================================================
FILE: addons/com.heroiclabs.nakama/Satori/SatoriClient.gd
================================================
extends RefCounted

## A client for the API in Satori Server.
class_name SatoriClient

#region Properties

var _host
## The host address of the server.
var host : String:
	get:
		return _host

var _port
## The port number of the server.
var port : int:
	get:
		return _port

var _scheme
## The protocol scheme used to connect with the server. Must be either "http" or "https".
var scheme : String:
	get:
		return _scheme

## The key used to authenticate with the server without a session.
var api_key : String

## Set the timeout in seconds on requests sent to the server.
var timeout : int

var _api_client : SatoriAPI.ApiClient

var auto_refresh : bool = false:
	set(v):
		set_auto_refresh(v)
	get:
		return get_auto_refresh()

func get_auto_refresh():
	return _api_client.auto_refresh

func set_auto_refresh(p_value):
	_api_client.auto_refresh = p_value

#endregion

#region Initialization

func _init(p_adapter : SatoriHTTPAdapter,
	p_api_key : String,
	p_scheme : String,
	p_host : String,
	p_port : int,
	p_timeout : int):

	api_key = p_api_key
	_scheme = p_scheme
	_host = p_host
	_port = p_port
	timeout = p_timeout
	_api_client = SatoriAPI.ApiClient.new(_scheme + "://" + _host + ":" + str(_port), p_adapter, SatoriAPI, api_key, p_timeout)

#endregion

#region Client APIs

## Authenticate against the server.
## [p_id]: An optional user id.
## [p_default_properties]: Optional default properties to update with this call.
## If not set, properties are left as they are on the server.
## [p_custom_properties]: Optional custom properties to update with this call.
## If not set, properties are left as they are on the server.
func authenticate_async(p_id: String, p_default_properties: Dictionary = {}, p_custom_properties: Dictionary = {}) -> SatoriSession:
	return _parse_session(await _api_client.authenticate_async(api_key, "",
		SatoriAPI.ApiAuthenticateRequest.create(SatoriAPI, {
			"id": p_id,
			"default": p_default_properties,
			"custom": p_custom_properties
		})))

## Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
## [p_session]: The session of the user.
func authenticate_logout_async(p_session: SatoriSession) -> SatoriAsyncResult:
	return await _api_client.authenticate_logout_async(p_session,
		SatoriAPI.ApiAuthenticateLogoutRequest.create(SatoriAPI, {
			"refresh_token": p_session.refresh_token,
			"token": p_session.token
		}))

# Parses the Satori API session and returns a SatoriSession object.
func _parse_session(p_session: SatoriAPI.ApiSession) -> SatoriSession:
	if p_session.is_exception():
		return SatoriSession.new(null, null, p_session.get_exception())
	
	return SatoriSession.new(p_session.token, p_session.refresh_token)

## Refresh a user's session using a refresh token retrieved from a previous authentication request.
## [p_sesison]: The session of the user.
func session_refresh_async(p_session : SatoriSession) -> SatoriSession:
	return _parse_session(await _api_client.authenticate_refresh_async(api_key, "",
		SatoriAPI.ApiAuthenticateRefreshRequest.create(SatoriAPI, {
			"refresh_token": p_session.refresh_token,
		})
	))

## Send an event for this session.
## [p_session]: The session of the user.
## [p_event]: The event which will be sent.
func event_async(p_session: SatoriSession, p_event: NakamaEvent) -> SatoriAsyncResult:
	return await events_async(p_session, [
		p_event
	])

## Send a batch of events for this session.
## [p_session]: The session of the user.
## [p_events]: The batch of events which will be sent.
func events_async(p_session: SatoriSession, p_events: Array) -> SatoriAsyncResult:
	var p_dict = {
		"events": p_events.map(func(e):
			return e.to_api_event_dict())
	}
	
	var req = SatoriAPI.ApiEventRequest.create(SatoriAPI, p_dict)
	return await _api_client.event_async(p_session,
		req)

## Get all experiments data.
## [p_session]: The session of the user.
func get_all_experiments_async(p_session: SatoriSession) -> SatoriAsyncResult:
	return await _api_client.get_experiments_async(p_session)

## Get specific experiments data.
## [p_session]: The session of the user.
## [p_names]: Experiment names.
func get_experiments_async(p_session: SatoriSession, p_names: Array) -> SatoriAPI.ApiExperimentList:
	return await _api_client.get_experiments_async(p_session, p_names)

## Get a single flag for this identity.
## This method will return the default value
## specified and will not raise an exception if the network is unavailable
## [p_session]: The session of the user.
## [p_name]: The name of the flag.
## [p_default]: The default value if the server is unreachable.
func get_flag_async(p_session: SatoriSession, p_name: String, p_default: String = "") -> SatoriAPI.ApiFlag:
	var p_names = [p_name]
	var flags = await get_flags_async(p_session, p_names)

	if flags.is_exception():
		return SatoriAPI.ApiFlag.create(SatoriAPI, {
			"name": p_name,
			"value": p_default
		})
	
	for flag in flags.flags:
		if flag.name == p_name:
			return flag
	
	return null

## List all available flags for this identity.
## [p_session]: The session of the user.
## [p_names]: Flag names, if empty all flags will be returned.
func get_flags_async(p_session: SatoriSession, p_names: Array) -> SatoriAPI.ApiFlagList:
	return await _api_client.get_flags_async(p_session.token, p_names)

## List available live events.
## [p_session]: The session of the user.
## [p_names]: Live event names, if null or empty all live events are returned.
func get_live_events_async(p_session: SatoriSession, p_names: Array = []) -> SatoriAPI.ApiLiveEventList:
	return await _api_client.get_live_events_async(p_session, p_names)

## Identify a session with a new ID.
## [p_session]: The session of the user.
## [p_id]: Identity ID to enrich the current session and return a new session.
## The old session will no longer be usable.
## Must be between eight and 128 characters (inclusive).
## Must be an alphanumeric string with only underscores and hyphens allowed.
## [p_default_properties]: The default properties.
## [p_custom_properties]: The custom event properties.
func identify_async(p_session: SatoriSession, p_id: String, p_default_properties: Dictionary = {}, p_custom_properties: Dictionary = {}) -> SatoriSession:
	var req = SatoriAPI.ApiIdentifyRequest.create(SatoriAPI, {
		"id": p_id,
		"default": p_default_properties,
		"custom": p_custom_properties
	})
	return _parse_session(await _api_client.identify_async(p_session, req))

## List properties associated with this identity.
## [p_session]: The session of the user.
func list_properties_async(p_session: SatoriSession) -> SatoriAsyncResult:
	return await _api_client.list_properties_async(p_session)

## Update properties associated with this identity.
## [p_session]: The session of the user.
## [p_default_properties]: The default properties to update.
## [p_custom_properties]: The custom properties to update.
## [p_recompute]: Whether or not to recompute the user's audience membership immediately after property update.
func update_properties_async(p_session: SatoriSession, p_default_properties: Dictionary, p_custom_properties: Dictionary, p_recompute: bool = false) -> SatoriAsyncResult:
	var req = SatoriAPI.ApiUpdatePropertiesRequest.create(SatoriAPI, {
		"default": p_default_properties,
		"custom": p_custom_properties,
		"recompute": p_recompute
	})
	return await _api_client.update_properties_async(p_session, req)

## Delete the caller's identity and associated data.
## [p_session]: The session of the user.
func delete_identity_async(p_session: SatoriSession) -> SatoriAsyncResult:
	return await _api_client.delete_identity_async(p_session)

#endregion


================================================
FILE: addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd
================================================
@tool
extends Node

# An adapter which implements the HTTP protocol.
class_name SatoriHTTPAdapter

# The logger to use with the adapter.
var logger : RefCounted = SatoriLogger.new()

# The timeout for requests
var timeout : int = 3
# If request should be automatically retried when a network error occurs.
var auto_retry : bool = true
# The maximum number of time a request will be retried when auto_retry is true
var auto_retry_count : int = 3
var auto_retry_backoff_base : int = 10
# Whether or not to use threads when making HTTP requests.
var use_threads : bool = true

var _pending = {}
var id : int = 0

class AsyncRequest:
	var id : int
	var request : HTTPRequest
	var uri : String
	var method : int
	var headers : PackedStringArray
	var body : PackedByteArray
	var retry_count := 3
	var backoff_time := 10
	var logger : SatoriLogger

	var cancelled = false
	var result : int = HTTPRequest.RESULT_NO_RESPONSE
	var response_code : int = -1
	var response_body : PackedByteArray
	var timer : SceneTreeTimer = null
	var cur_try : int = 1
	var rng = RandomNumberGenerator.new()

	func _init(p_id : int, p_request : HTTPRequest, p_uri : String,
			p_method : int, p_headers : PackedStringArray, p_body : PackedByteArray,
			p_retry_count : int, p_backoff_time : int, p_logger : SatoriLogger):
		rng.seed = Time.get_ticks_usec()
		id = p_id
		request = p_request
		uri = p_uri
		method = p_method
		headers = p_headers
		body = p_body
		retry_count = p_retry_count
		backoff_time = p_backoff_time
		logger = p_logger

	func should_retry():
		return cur_try < retry_count and not cancelled

	func retry():
		var time = pow(backoff_time, cur_try) * rng.randf_range(0.5, 1)
		logger.debug("Retrying request %d. Tries left: %d. Backoff: %d ms" % [
			id, retry_count - cur_try, time
		])
		cur_try += 1
		await backoff(time)
		if cancelled:
			return
		return await make_request()

	func make_request():
		var err = request.request(uri, headers, method, body.get_string_from_utf8())
		if err != OK:
			await request.get_tree().process_frame
			result = HTTPRequest.RESULT_CANT_CONNECT
			logger.debug("Request %d failed to start, error: %d" % [id, err])
			return

		var args = await request.request_completed
		result = args[0]
		response_code = args[1]
		response_body = args[3]

	func backoff(p_time : int):
		timer = request.get_tree().create_timer(p_time / 1000.0)
		await timer.timeout
		timer = null

	func cancel():
		cancelled = true
		request.cancel_request()
		if timer:
			timer.time_left = 0
		else:
			request.call_deferred("emit_signal", "request_completed", HTTPRequest.RESULT_REQUEST_FAILED, 0, [], [])

	func parse_result():
		if cancelled:
			return SatoriException.new("Request cancelled", -1, -1, true)
		elif result != HTTPRequest.RESULT_SUCCESS:
			if result == null:
				result = 0
			return SatoriException.new("HTTPRequest failed!", result)

		var json = JSON.new()

		var json_error = json.parse(response_body.get_string_from_utf8())
		if json_error != OK:
			logger.debug("Unable to parse request %d response. JSON error: %d, JSON error message: %s, response code: %d" % [
				id, json_error, json.get_error_message(), response_code
			])
			return SatoriException.new("Failed to decode JSON response", response_code)

		var parsed = json.get_data()

		if response_code != HTTPClient.RESPONSE_OK:
			var error = ""
			var code = -1
			if typeof(parsed) == TYPE_DICTIONARY:
				if "message" in parsed:
					error = parsed["message"]
				elif "error" in parsed:
					error = parsed["error"]
				else:
					error = str(parsed)
				code = parsed["code"] if "code" in parsed else -1
			else:
				error = str(parsed)
			if typeof(error) == TYPE_DICTIONARY:
				error = JSON.stringify(error)
			logger.debug("Request %d returned response code: %d, RPC code: %d, error: %s" % [
				id, response_code, code, error
			])
			return SatoriException.new(error, response_code, code)

		return parsed


# Send a HTTP request.
# @param method - HTTP method to use for this request.
# @param uri - The fully qualified URI to use.
# @param headers - Request headers to set.
# @param body - Request content body to set.
# @param timeoutSec - Request timeout.
# Returns a task which resolves to the contents of the response.
func send_async(p_method : String, p_uri : String, p_headers : Dictionary, p_body : PackedByteArray):
	var req = HTTPRequest.new()
	req.timeout = timeout
	if use_threads and OS.get_name() != 'Web':
		req.use_threads = true # Threads not available nor needed on the web.

	# Parse method
	var method = HTTPClient.METHOD_GET
	if p_method == "POST":
		method = HTTPClient.METHOD_POST
	elif p_method == "PUT":
		method = HTTPClient.METHOD_PUT
	elif p_method == "DELETE":
		method = HTTPClient.METHOD_DELETE
	elif p_method == "HEAD":
		method = HTTPClient.METHOD_HEAD
	var headers = PackedStringArray()

	# Parse headers
	headers.append("Accept: application/json")
	for k in p_headers:
		headers.append("%s: %s" % [k, p_headers[k]])

	id += 1
	var retry = auto_retry_count if auto_retry else 0
	var backoff = auto_retry_backoff_base
	_pending[id] = AsyncRequest.new(id, req, p_uri, method, headers, p_body, retry, backoff, logger)

	logger.debug("Sending request [ID: %d, Method: %s, Uri: %s, Headers: %s, Body: %s, Timeout: %d, Retries: %d, Backoff base: %d ms]" % [
		id, p_method, p_uri, p_headers, p_body.get_string_from_utf8(), timeout, retry, backoff
	])

	add_child(req)

	return await _send_async(id, _pending)

func get_last_token():
	return id

func cancel_request(p_token):
	if _pending.has(p_token):
		_pending[p_token].cancel()

static func _clear_request(p_request : AsyncRequest, p_pending : Dictionary, p_id : int):
	if not p_request.request.is_queued_for_deletion():
		p_request.logger.debug("Freeing request %d" % p_id)
		p_request.request.queue_free()
		p_pending.erase(p_id)

static func _send_async(p_id : int, p_pending : Dictionary):

	var req : AsyncRequest = p_pending[p_id]
	await req.make_request()

	while req.result != HTTPRequest.RESULT_SUCCESS:
		req.logger.debug("Request %d failed with result: %d, response code: %d" % [
			p_id, req.result, req.response_code
		])
		if not req.should_retry():
			break
		await req.retry()

	_clear_request(req, p_pending, p_id)
	return req.parse_result()


================================================
FILE: addons/com.heroiclabs.nakama/Satori/SatoriSession.gd
================================================
extends  SatoriAsyncResult
class_name SatoriSession

var _token: String = ""
var token: String:
    get:
        return _token

var _refresh_token: String = ""
var refresh_token: String:
    get:
        return _refresh_token

var _expire_time: int = 0
var expire_time: int:
    get:
        return _expire_time

var expired: bool:
    get:
        return is_expired()

var _refresh_expire_time: int = 0
var refresh_expire_time: int:
    get:
        return _refresh_expire_time

var _identity_id: String = ""
var identity_id: String:
    get:
        return _identity_id

var _valid : bool = false
var valid : bool:
    get:
        return _valid

func is_expired() -> bool:
    return _expire_time < Time.get_unix_time_from_system()

func would_expire_in(p_secs : int) -> bool:
    return _expire_time < Time.get_unix_time_from_system() + p_secs

func has_refresh_expired(offset: float) -> bool:
    return _expire_time < offset

func is_refresh_expired() -> bool:
    return _refresh_expire_time < Time.get_unix_time_from_system()

func is_valid():
    return _valid

# Initializes a new instance of the SatoriSession class.
# 
# @param p_token - The authentication token.
# @param p_refresh_token - The refresh token.
# @param p_exception - The exception to be thrown, if any.
func _init(p_token = null, p_refresh_token = null, p_exception = null):
    super(p_exception)
    
    _refresh_expire_time = 0
    if p_token:
        _update(p_token, p_refresh_token)

func _update(p_token, p_refresh_token):
    _token = p_token
    _refresh_token = p_refresh_token
    
    var decoded = _jwt_unpack(p_token)
    if decoded.is_empty():
        _valid = false
        return
    
    _valid = true
    _expire_time = int(decoded.get("exp", 0))
    _identity_id = str(decoded.get("iid", ""))
    _refresh_expire_time = int(_jwt_unpack(refresh_token).get("exp", 0)) if !refresh_token.is_empty() else 0

func _to_string():
    if is_exception():
        return get_exception()._to_string()
    
    return "Session<AuthToken=%s, ExpireTime=%d, RefreshToken=%s, RefreshExpireTime=%d, IdentityId=%s>" % [
        _token, _expire_time, _refresh_token, _refresh_expire_time, identity_id]

func _jwt_unpack(p_token : String) -> Dictionary:
    # Hack decode JSON payload from JWT.
    if p_token.find(".") == -1:
        _ex = SatoriException.new("Missing payload: %s" % p_token)
        return {}
    var payload = p_token.split('.')[1];
    var pad_length = ceil(payload.length() / 4.0) * 4;
    # Pad base64
    for i in range(0, pad_length - payload.length()):
        payload += "="
    payload = payload.replace("-", "+").replace("_", "/")
    var unpacked = Marshalls.base64_to_utf8(payload)
    
    var json = JSON.new()
    var error = json.parse(unpacked)

    if error == OK:
        var decoded = json.get_data()
        if typeof(decoded) == TYPE_DICTIONARY:
            return decoded
    _ex = SatoriException.new("Unable to unpack token: %s" % p_token)
    return {}

================================================
FILE: addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd
================================================
extends RefCounted
class_name SatoriAsyncResult

var exception : SatoriException:
	set(v):
		pass
	get:
		return get_exception()

var _ex = null

func _init(p_ex = null):
	_ex = p_ex

func is_exception():
	return get_exception() != null

func was_cancelled():
	return is_exception() and get_exception().cancelled

func get_exception() -> SatoriException:
	return _ex as SatoriException

func _to_string():
	if is_exception():
		return get_exception()._to_string()
	return "SatoriAsyncResult<>"

static func _safe_ret(p_obj, p_type : GDScript):
	if is_instance_of(p_obj, p_type):
		return p_obj
	elif p_obj is SatoriException:
		return p_type.new(p_obj)
	return p_type.new(SatoriException.new())


================================================
FILE: addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd
================================================
extends RefCounted

# An exception generated during a request.
# Usually contains at least an error message.
class_name SatoriException

var _status_code : int = -1
var status_code : int:
	set(v):
		pass
	get:
		return _status_code

var _grpc_status_code : int = -1
var grpc_status_code : int:
	set(v):
		pass
	get:
		return _grpc_status_code

var _message : String = ""
var message : String:
	set(v):
		pass
	get:
		return _message

var _cancelled : bool = false
var cancelled : bool:
	set(v):
		pass
	get:
		return _cancelled

func _init(p_message : String = "", p_status_code : int = -1, p_grpc_status_code : int = -1, p_cancelled : bool = false):
	_status_code = p_status_code
	_grpc_status_code = p_grpc_status_code
	_message = p_message
	_cancelled = p_cancelled

func _to_string() -> String:
	return "SatoriException(StatusCode={%s}, Message='{%s}', GrpcStatusCode={%s})" % [_status_code, _message, _grpc_status_code]


================================================
FILE: addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd
================================================
extends RefCounted
class_name SatoriLogger

enum LOG_LEVEL {NONE, ERROR, WARNING, INFO, VERBOSE, DEBUG}

var _level = LOG_LEVEL.ERROR
var _module = "Satori"

func _init(p_module : String = "Satori", p_level : int = LOG_LEVEL.ERROR):
	_level = p_level
	_module = p_module

func _log(level : int, msg):
	if level <= _level:
		if level == LOG_LEVEL.ERROR:
			printerr("=== %s : ERROR === %s" % [_module, str(msg)])
		else:
			var what = "=== UNKNOWN === "
			for k in LOG_LEVEL:
				if level == LOG_LEVEL[k]:
					what = "=== %s : %s === " % [_module, k]
					break
			print(what + str(msg))

func error(msg):
	_log(LOG_LEVEL.ERROR, msg)

func warning(msg):
	_log(LOG_LEVEL.WARNING, msg)

func info(msg):
	_log(LOG_LEVEL.INFO, msg)

func verbose(msg):
	_log(LOG_LEVEL.VERBOSE, msg)

func debug(msg):
	_log(LOG_LEVEL.DEBUG, msg)


================================================
FILE: addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd
================================================
extends RefCounted
class_name SatoriSerializer

static func serialize(p_obj : Object) -> Dictionary:
	var out = {}
	var schema = p_obj.get("_SCHEMA")
	if schema == null:
		return {} # No schema defined
	for k in schema:
		var prop = schema[k]
		var val = p_obj.get(prop["name"])
		if val == null:
			continue
		var type = prop["type"]
		var content = prop.get("content", TYPE_NIL)
		if typeof(content) == TYPE_STRING:
			content = TYPE_OBJECT
		var val_type = typeof(val)
		match val_type:
			TYPE_OBJECT: # Simple objects
				out[k] = serialize(val)
			TYPE_ARRAY: # Array of objects
				var arr = []
				if val.size() > 0 and typeof(val[0]) == TYPE_OBJECT: # Array of objects
					for e in val:
						arr.append(serialize(e))
				else:
					arr = val
				out[k] = arr
			TYPE_PACKED_INT32_ARRAY, TYPE_PACKED_STRING_ARRAY: # Array of ints, bools, or strings
				var arr = []
				for e in val:
					if content == TYPE_BOOL:
						e = bool(e)
					if typeof(e) != content:
						continue
					arr.append(e)
				out[k] = arr
			TYPE_DICTIONARY: # Maps
				var dict = {}
				if content == TYPE_OBJECT: # Map of objects
					for l in val:
						if typeof(val[l]) != TYPE_OBJECT:
							continue
						dict[l] = serialize(val[l])
				else: # Map of simple types
					for l in val:
						var e = val[l]
						if content == TYPE_FLOAT:
							e = float(e)
						elif content == TYPE_INT:
							e = int(e)
						elif content == TYPE_BOOL:
							e = bool(e)
						if typeof(e) != content:
							continue
						dict[l] = e
				out[k] = dict
			_:
				out[k] = val
	return out

static func deserialize(p_ns : GDScript, p_cls_name : String, p_dict : Dictionary) -> Object:
	var cls : GDScript = p_ns.get(p_cls_name)
	var schema = cls.get("_SCHEMA")
	if schema == null:
		return SatoriException.new() # No schema defined
	var obj = cls.new()
	for k in schema:
		var prop = schema[k]
		var pname = prop["name"]
		var type = prop["type"]
		var required = prop["required"]
		var content = prop.get("content", TYPE_NIL)
		var type_cmp = type
		if typeof(type) == TYPE_STRING: # A class
			type_cmp = TYPE_DICTIONARY
		if type_cmp == TYPE_PACKED_STRING_ARRAY or type_cmp == TYPE_PACKED_INT32_ARRAY: # A specialized array
			type_cmp = TYPE_ARRAY

		var content_cmp = content
		if typeof(content) == TYPE_STRING: # A dictionary or array of classes
			content_cmp = TYPE_DICTIONARY

		var val = p_dict.get(k, null)

		# Ints might and up being recognized as floats. Change that if needed
		if type_cmp == TYPE_INT:
			if typeof(val) == TYPE_FLOAT:
				val = int(val)
			elif typeof(val) == TYPE_STRING and val.is_valid_int():
				val = val.to_int()

		if typeof(val) == type_cmp:
			if typeof(type) == TYPE_STRING:
				obj.set(pname, deserialize(p_ns, type, val))
			elif type_cmp == TYPE_DICTIONARY:
				var v = {}
				for l in val:
					if typeof(content) == TYPE_STRING:
						v[l] = deserialize(p_ns, content, val[l])
					elif content == TYPE_FLOAT:
						v[l] = float(val[l])
					elif content == TYPE_INT:
						v[l] = int(val[l])
					elif content == TYPE_BOOL:
						v[l] = bool(val[l])
					else:
						v[l] = str(val[l])
				obj.set(pname, v)
			elif type_cmp == TYPE_ARRAY:
				var v
				match content:
					TYPE_INT, TYPE_BOOL: v = PackedInt32Array()
					TYPE_STRING: v = PackedStringArray()
					_: v = Array()
				for e in val:
					if typeof(e) == TYPE_DICTIONARY: 
						v.append(e) # Avoid deserialization if e is already a dictionary
					elif typeof(content) == TYPE_STRING:
						v.append(deserialize(p_ns, content, e))
					elif content == TYPE_FLOAT:
						v.append(float(e))
					elif content == TYPE_INT:
						v.append(int(e))
					elif content == TYPE_BOOL:
						v.append(bool(e))
					else:
						v.append(str(e))
				obj.set(pname, v)
			else:
				obj.set(pname, val)
		elif required:
			obj._ex = SatoriException.new("ERROR [%s]: Missing or invalid required prop %s = %s:\n\t%s" % [p_cls_name, prop, p_dict.get(k), p_dict])
			return obj
	return obj


###
# Compatibility with Godot 3.1 which does not expose String.http_escape
###
const HEX = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]

static func escape_http(p_str : String) -> String:
	var out : String = ""
	for o in p_str:
		if (o == '.' or o == '-' or o == '_' or o == '~' or
			(o >= 'a' and o <= 'z') or
			(o >= 'A' and o <= 'Z') or
			(o >= '0' and o <= '9')):
			out += o
		else:
			for b in o.to_utf8_buffer():
				out += "%%%s" % to_hex(b)
	return out

static func to_hex(p_val : int) -> String:
	var v := p_val
	var o := ""
	while v != 0:
		o = HEX[v % 16] + o
		v /= 16
	return o


================================================
FILE: addons/com.heroiclabs.nakama/Satori.gd
================================================
@tool
extends Node

# The default host address of the server.
const DEFAULT_HOST : String = "127.0.0.1"

# The default port number of the server.
const DEFAULT_PORT : int = 7450

# The default timeout for the connections.
const DEFAULT_TIMEOUT = 15

# The default protocol scheme for the client connection.
const DEFAULT_CLIENT_SCHEME : String = "http"

# The default log level for the Satori logger.
const DEFAULT_LOG_LEVEL = SatoriLogger.LOG_LEVEL.DEBUG

var _http_adapter = null
var logger = SatoriLogger.new()

func _ready() -> void:
	process_mode = Node.PROCESS_MODE_ALWAYS

func get_client_adapter() -> SatoriHTTPAdapter:
	if _http_adapter == null:
		_http_adapter = SatoriHTTPAdapter.new()
		_http_adapter.logger = logger
		_http_adapter.name = "SatoriHTTPAdapter"
		add_child(_http_adapter)
	return _http_adapter

func create_client(p_api_key : String,
		p_host : String = DEFAULT_HOST,
		p_port : int = DEFAULT_PORT,
		p_scheme : String = DEFAULT_CLIENT_SCHEME,
		p_timeout : int = DEFAULT_TIMEOUT,
		p_log_level : int = DEFAULT_LOG_LEVEL,
		) -> SatoriClient:
	logger._level = p_log_level
	return SatoriClient.new(get_client_adapter(), p_api_key, p_scheme, p_host, p_port, p_timeout)


================================================
FILE: addons/com.heroiclabs.nakama/api/NakamaAPI.gd
================================================
### Code generated by codegen/main.go. DO NOT EDIT. ###

extends RefCounted
class_name NakamaAPI

# A single user-role pair.
class GroupUserListGroupUser extends NakamaAsyncResult:

	const _SCHEMA = {
		"state": {"name": "_state", "type": TYPE_INT, "required": false},
		"user": {"name": "_user", "type": "ApiUser", "required": false},
	}

	# Their relationship to the group.
	var _state
	var state : int:
		get:
			return 0 if not _state is int else int(_state)

	# User.
	var _user
	var user : ApiUser:
		get:
			return _user as ApiUser

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> GroupUserListGroupUser:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "GroupUserListGroupUser", p_dict), GroupUserListGroupUser) as GroupUserListGroupUser

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "state: %s, " % _state
		output += "user: %s, " % _user
		return output

# A single group-role pair.
class UserGroupListUserGroup extends NakamaAsyncResult:

	const _SCHEMA = {
		"group": {"name": "_group", "type": "ApiGroup", "required": false},
		"state": {"name": "_state", "type": TYPE_INT, "required": false},
	}

	# Group.
	var _group
	var group : ApiGroup:
		get:
			return _group as ApiGroup

	# The user's relationship to the group.
	var _state
	var state : int:
		get:
			return 0 if not _state is int else int(_state)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> UserGroupListUserGroup:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "UserGroupListUserGroup", p_dict), UserGroupListUserGroup) as UserGroupListUserGroup

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "group: %s, " % _group
		output += "state: %s, " % _state
		return output

# Record values to write.
class WriteLeaderboardRecordRequestLeaderboardRecordWrite extends NakamaAsyncResult:

	const _SCHEMA = {
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
		"score": {"name": "_score", "type": TYPE_STRING, "required": false},
		"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
	}

	# Optional record metadata.
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# Operator override.
	var _operator
	var operator : int:
		get:
			return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator

	# The score value to submit.
	var _score
	var score : String:
		get:
			return "" if not _score is String else String(_score)

	# An optional secondary value.
	var _subscore
	var subscore : String:
		get:
			return "" if not _subscore is String else String(_subscore)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteLeaderboardRecordRequestLeaderboardRecordWrite:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteLeaderboardRecordRequestLeaderboardRecordWrite", p_dict), WriteLeaderboardRecordRequestLeaderboardRecordWrite) as WriteLeaderboardRecordRequestLeaderboardRecordWrite

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "metadata: %s, " % _metadata
		output += "operator: %s, " % _operator
		output += "score: %s, " % _score
		output += "subscore: %s, " % _subscore
		return output

# Record values to write.
class WriteTournamentRecordRequestTournamentRecordWrite extends NakamaAsyncResult:

	const _SCHEMA = {
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
		"score": {"name": "_score", "type": TYPE_STRING, "required": false},
		"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
	}

	# A JSON object of additional properties (optional).
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# Operator override.
	var _operator
	var operator : int:
		get:
			return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator

	# The score value to submit.
	var _score
	var score : String:
		get:
			return "" if not _score is String else String(_score)

	# An optional secondary value.
	var _subscore
	var subscore : String:
		get:
			return "" if not _subscore is String else String(_subscore)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteTournamentRecordRequestTournamentRecordWrite:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteTournamentRecordRequestTournamentRecordWrite", p_dict), WriteTournamentRecordRequestTournamentRecordWrite) as WriteTournamentRecordRequestTournamentRecordWrite

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "metadata: %s, " % _metadata
		output += "operator: %s, " % _operator
		output += "score: %s, " % _score
		output += "subscore: %s, " % _subscore
		return output

# A user with additional account details. Always the current user.
class ApiAccount extends NakamaAsyncResult:

	const _SCHEMA = {
		"custom_id": {"name": "_custom_id", "type": TYPE_STRING, "required": false},
		"devices": {"name": "_devices", "type": TYPE_ARRAY, "required": false, "content": "ApiAccountDevice"},
		"disable_time": {"name": "_disable_time", "type": TYPE_STRING, "required": false},
		"email": {"name": "_email", "type": TYPE_STRING, "required": false},
		"user": {"name": "_user", "type": "ApiUser", "required": false},
		"verify_time": {"name": "_verify_time", "type": TYPE_STRING, "required": false},
		"wallet": {"name": "_wallet", "type": TYPE_STRING, "required": false},
	}

	# The custom id in the user's account.
	var _custom_id
	var custom_id : String:
		get:
			return "" if not _custom_id is String else String(_custom_id)

	# The devices which belong to the user's account.
	var _devices
	var devices : Array:
		get:
			return Array() if not _devices is Array else Array(_devices)

	# The UNIX time when the user's account was disabled/banned.
	var _disable_time
	var disable_time : String:
		get:
			return "" if not _disable_time is String else String(_disable_time)

	# The email address of the user.
	var _email
	var email : String:
		get:
			return "" if not _email is String else String(_email)

	# The user object.
	var _user
	var user : ApiUser:
		get:
			return _user as ApiUser

	# The UNIX time when the user's email was verified.
	var _verify_time
	var verify_time : String:
		get:
			return "" if not _verify_time is String else String(_verify_time)

	# The user's wallet data.
	var _wallet
	var wallet : String:
		get:
			return "" if not _wallet is String else String(_wallet)

	var _wallet_dict = null
	var wallet_dict : Dictionary:
		get:
			if _wallet_dict == null:
				if _wallet == null:
					return {}
				var json = JSON.new()
				if json.parse(_wallet) != OK:
					return {}
				_wallet_dict = json.get_data()
			return _wallet_dict as Dictionary


	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccount:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccount", p_dict), ApiAccount) as ApiAccount

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "custom_id: %s, " % _custom_id
		output += "devices: %s, " % [_devices]
		output += "disable_time: %s, " % _disable_time
		output += "email: %s, " % _email
		output += "user: %s, " % _user
		output += "verify_time: %s, " % _verify_time
		output += "wallet: %s, " % _wallet
		return output

# Send a Apple Sign In token to the server. Used with authenticate/link/unlink.
class ApiAccountApple extends NakamaAsyncResult:

	const _SCHEMA = {
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# The ID token received from Apple to validate.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountApple:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountApple", p_dict), ApiAccountApple) as ApiAccountApple

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "token: %s, " % _token
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a custom ID to the server. Used with authenticate/link/unlink.
class ApiAccountCustom extends NakamaAsyncResult:

	const _SCHEMA = {
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# A custom identifier.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountCustom:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountCustom", p_dict), ApiAccountCustom) as ApiAccountCustom

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "id: %s, " % _id
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a device to the server. Used with authenticate/link/unlink and user.
class ApiAccountDevice extends NakamaAsyncResult:

	const _SCHEMA = {
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# A device identifier. Should be obtained by a platform-specific device API.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountDevice:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountDevice", p_dict), ApiAccountDevice) as ApiAccountDevice

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "id: %s, " % _id
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send an email with password to the server. Used with authenticate/link/unlink.
class ApiAccountEmail extends NakamaAsyncResult:

	const _SCHEMA = {
		"email": {"name": "_email", "type": TYPE_STRING, "required": false},
		"password": {"name": "_password", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# A valid RFC-5322 email address.
	var _email
	var email : String:
		get:
			return "" if not _email is String else String(_email)

	# A password for the user account.
	var _password
	var password : String:
		get:
			return "" if not _password is String else String(_password)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountEmail:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountEmail", p_dict), ApiAccountEmail) as ApiAccountEmail

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "email: %s, " % _email
		output += "password: %s, " % _password
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a Facebook token to the server. Used with authenticate/link/unlink.
class ApiAccountFacebook extends NakamaAsyncResult:

	const _SCHEMA = {
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# The OAuth token received from Facebook to access their profile API.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebook:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebook", p_dict), ApiAccountFacebook) as ApiAccountFacebook

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "token: %s, " % _token
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a Facebook Instant Game token to the server. Used with authenticate/link/unlink.
class ApiAccountFacebookInstantGame extends NakamaAsyncResult:

	const _SCHEMA = {
		"signed_player_info": {"name": "_signed_player_info", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	#
	var _signed_player_info
	var signed_player_info : String:
		get:
			return "" if not _signed_player_info is String else String(_signed_player_info)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebookInstantGame:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebookInstantGame", p_dict), ApiAccountFacebookInstantGame) as ApiAccountFacebookInstantGame

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "signed_player_info: %s, " % _signed_player_info
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send Apple's Game Center account credentials to the server. Used with authenticate/link/unlink.
class ApiAccountGameCenter extends NakamaAsyncResult:

	const _SCHEMA = {
		"bundle_id": {"name": "_bundle_id", "type": TYPE_STRING, "required": false},
		"player_id": {"name": "_player_id", "type": TYPE_STRING, "required": false},
		"public_key_url": {"name": "_public_key_url", "type": TYPE_STRING, "required": false},
		"salt": {"name": "_salt", "type": TYPE_STRING, "required": false},
		"signature": {"name": "_signature", "type": TYPE_STRING, "required": false},
		"timestamp_seconds": {"name": "_timestamp_seconds", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# Bundle ID (generated by GameCenter).
	var _bundle_id
	var bundle_id : String:
		get:
			return "" if not _bundle_id is String else String(_bundle_id)

	# Player ID (generated by GameCenter).
	var _player_id
	var player_id : String:
		get:
			return "" if not _player_id is String else String(_player_id)

	# The URL for the public encryption key.
	var _public_key_url
	var public_key_url : String:
		get:
			return "" if not _public_key_url is String else String(_public_key_url)

	# A random "NSString" used to compute the hash and keep it randomized.
	var _salt
	var salt : String:
		get:
			return "" if not _salt is String else String(_salt)

	# The verification signature data generated.
	var _signature
	var signature : String:
		get:
			return "" if not _signature is String else String(_signature)

	# Time since UNIX epoch when the signature was created.
	var _timestamp_seconds
	var timestamp_seconds : String:
		get:
			return "" if not _timestamp_seconds is String else String(_timestamp_seconds)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGameCenter:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGameCenter", p_dict), ApiAccountGameCenter) as ApiAccountGameCenter

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "bundle_id: %s, " % _bundle_id
		output += "player_id: %s, " % _player_id
		output += "public_key_url: %s, " % _public_key_url
		output += "salt: %s, " % _salt
		output += "signature: %s, " % _signature
		output += "timestamp_seconds: %s, " % _timestamp_seconds
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a Google token to the server. Used with authenticate/link/unlink.
class ApiAccountGoogle extends NakamaAsyncResult:

	const _SCHEMA = {
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# The OAuth token received from Google to access their profile API.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGoogle:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGoogle", p_dict), ApiAccountGoogle) as ApiAccountGoogle

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "token: %s, " % _token
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# Send a Steam token to the server. Used with authenticate/link/unlink.
class ApiAccountSteam extends NakamaAsyncResult:

	const _SCHEMA = {
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# The account token received from Steam to access their profile API.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountSteam:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountSteam", p_dict), ApiAccountSteam) as ApiAccountSteam

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "token: %s, " % _token
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# A message sent on a channel.
class ApiChannelMessage extends NakamaAsyncResult:

	const _SCHEMA = {
		"channel_id": {"name": "_channel_id", "type": TYPE_STRING, "required": false},
		"code": {"name": "_code", "type": TYPE_INT, "required": false},
		"content": {"name": "_content", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false},
		"message_id": {"name": "_message_id", "type": TYPE_STRING, "required": false},
		"persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false},
		"room_name": {"name": "_room_name", "type": TYPE_STRING, "required": false},
		"sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
		"user_id_one": {"name": "_user_id_one", "type": TYPE_STRING, "required": false},
		"user_id_two": {"name": "_user_id_two", "type": TYPE_STRING, "required": false},
		"username": {"name": "_username", "type": TYPE_STRING, "required": false},
	}

	# The channel this message belongs to.
	var _channel_id
	var channel_id : String:
		get:
			return "" if not _channel_id is String else String(_channel_id)

	# The code representing a message type or category.
	var _code
	var code : int:
		get:
			return 0 if not _code is int else int(_code)

	# The content payload.
	var _content
	var content : String:
		get:
			return "" if not _content is String else String(_content)

	# The UNIX time when the message was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The ID of the group, or an empty string if this message was not sent through a group channel.
	var _group_id
	var group_id : String:
		get:
			return "" if not _group_id is String else String(_group_id)

	# The unique ID of this message.
	var _message_id
	var message_id : String:
		get:
			return "" if not _message_id is String else String(_message_id)

	# True if the message was persisted to the channel's history, false otherwise.
	var _persistent
	var persistent : bool:
		get:
			return false if not _persistent is bool else bool(_persistent)

	# The name of the chat room, or an empty string if this message was not sent through a chat room.
	var _room_name
	var room_name : String:
		get:
			return "" if not _room_name is String else String(_room_name)

	# Message sender, usually a user ID.
	var _sender_id
	var sender_id : String:
		get:
			return "" if not _sender_id is String else String(_sender_id)

	# The UNIX time when the message was last updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	# The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
	var _user_id_one
	var user_id_one : String:
		get:
			return "" if not _user_id_one is String else String(_user_id_one)

	# The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
	var _user_id_two
	var user_id_two : String:
		get:
			return "" if not _user_id_two is String else String(_user_id_two)

	# The username of the message sender, if any.
	var _username
	var username : String:
		get:
			return "" if not _username is String else String(_username)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessage:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessage", p_dict), ApiChannelMessage) as ApiChannelMessage

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "channel_id: %s, " % _channel_id
		output += "code: %s, " % _code
		output += "content: %s, " % _content
		output += "create_time: %s, " % _create_time
		output += "group_id: %s, " % _group_id
		output += "message_id: %s, " % _message_id
		output += "persistent: %s, " % _persistent
		output += "room_name: %s, " % _room_name
		output += "sender_id: %s, " % _sender_id
		output += "update_time: %s, " % _update_time
		output += "user_id_one: %s, " % _user_id_one
		output += "user_id_two: %s, " % _user_id_two
		output += "username: %s, " % _username
		return output

# A list of channel messages, usually a result of a list operation.
class ApiChannelMessageList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
		"messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": "ApiChannelMessage"},
		"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
	}

	# Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
	var _cacheable_cursor
	var cacheable_cursor : String:
		get:
			return "" if not _cacheable_cursor is String else String(_cacheable_cursor)

	# A list of messages.
	var _messages
	var messages : Array:
		get:
			return Array() if not _messages is Array else Array(_messages)

	# The cursor to send when retrieving the next page, if any.
	var _next_cursor
	var next_cursor : String:
		get:
			return "" if not _next_cursor is String else String(_next_cursor)

	# The cursor to send when retrieving the previous page, if any.
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessageList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessageList", p_dict), ApiChannelMessageList) as ApiChannelMessageList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cacheable_cursor: %s, " % _cacheable_cursor
		output += "messages: %s, " % [_messages]
		output += "next_cursor: %s, " % _next_cursor
		output += "prev_cursor: %s, " % _prev_cursor
		return output

# Create a group with the current user as owner.
class ApiCreateGroupRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
		"max_count": {"name": "_max_count", "type": TYPE_INT, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
	}

	# A URL for an avatar image.
	var _avatar_url
	var avatar_url : String:
		get:
			return "" if not _avatar_url is String else String(_avatar_url)

	# A description for the group.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)

	# The language expected to be a tag which follows the BCP-47 spec.
	var _lang_tag
	var lang_tag : String:
		get:
			return "" if not _lang_tag is String else String(_lang_tag)

	# Maximum number of group members.
	var _max_count
	var max_count : int:
		get:
			return 0 if not _max_count is int else int(_max_count)

	# A unique name for the group.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)

	# Mark a group as open or not where only admins can accept members.
	var _open
	var open : bool:
		get:
			return false if not _open is bool else bool(_open)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiCreateGroupRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiCreateGroupRequest", p_dict), ApiCreateGroupRequest) as ApiCreateGroupRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "avatar_url: %s, " % _avatar_url
		output += "description: %s, " % _description
		output += "lang_tag: %s, " % _lang_tag
		output += "max_count: %s, " % _max_count
		output += "name: %s, " % _name
		output += "open: %s, " % _open
		return output

# Storage objects to delete.
class ApiDeleteStorageObjectId extends NakamaAsyncResult:

	const _SCHEMA = {
		"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
		"key": {"name": "_key", "type": TYPE_STRING, "required": false},
		"version": {"name": "_version", "type": TYPE_STRING, "required": false},
	}

	# The collection which stores the object.
	var _collection
	var collection : String:
		get:
			return "" if not _collection is String else String(_collection)

	# The key of the object within the collection.
	var _key
	var key : String:
		get:
			return "" if not _key is String else String(_key)

	# The version hash of the object.
	var _version
	var version : String:
		get:
			return "" if not _version is String else String(_version)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectId:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectId", p_dict), ApiDeleteStorageObjectId) as ApiDeleteStorageObjectId

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "collection: %s, " % _collection
		output += "key: %s, " % _key
		output += "version: %s, " % _version
		return output

# Batch delete storage objects.
class ApiDeleteStorageObjectsRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiDeleteStorageObjectId"},
	}

	# Batch of storage objects.
	var _object_ids
	var object_ids : Array:
		get:
			return Array() if not _object_ids is Array else Array(_object_ids)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectsRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectsRequest", p_dict), ApiDeleteStorageObjectsRequest) as ApiDeleteStorageObjectsRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "object_ids: %s, " % [_object_ids]
		return output

# Represents an event to be passed through the server to registered event handlers.
class ApiEvent extends NakamaAsyncResult:

	const _SCHEMA = {
		"external": {"name": "_external", "type": TYPE_BOOL, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"properties": {"name": "_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false},
	}

	# True if the event came directly from a client call, false otherwise.
	var _external
	var external : bool:
		get:
			return false if not _external is bool else bool(_external)

	# An event name, type, category, or identifier.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)

	# Arbitrary event property values.
	var _properties
	var properties : Dictionary:
		get:
			return Dictionary() if not _properties is Dictionary else _properties.duplicate()

	# The time when the event was triggered.
	var _timestamp
	var timestamp : String:
		get:
			return "" if not _timestamp is String else String(_timestamp)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "external: %s, " % _external
		output += "name: %s, " % _name
		var map_string : String = ""
		if typeof(_properties) == TYPE_DICTIONARY:
			for k in _properties:
				map_string += "{%s=%s}, " % [k, _properties[k]]
		output += "properties: [%s], " % map_string
		output += "timestamp: %s, " % _timestamp
		return output

# A friend of a user.
class ApiFriend extends NakamaAsyncResult:

	const _SCHEMA = {
		"state": {"name": "_state", "type": TYPE_INT, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
		"user": {"name": "_user", "type": "ApiUser", "required": false},
	}

	# The friend status.
	var _state
	var state : int:
		get:
			return 0 if not _state is int else int(_state)

	# Time of the latest relationship update.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	# The user object.
	var _user
	var user : ApiUser:
		get:
			return _user as ApiUser

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriend:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriend", p_dict), ApiFriend) as ApiFriend

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "state: %s, " % _state
		output += "update_time: %s, " % _update_time
		output += "user: %s, " % _user
		return output

# A collection of zero or more friends of the user.
class ApiFriendList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"friends": {"name": "_friends", "type": TYPE_ARRAY, "required": false, "content": "ApiFriend"},
	}

	# Cursor for the next page of results, if any.
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# The Friend objects.
	var _friends
	var friends : Array:
		get:
			return Array() if not _friends is Array else Array(_friends)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriendList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriendList", p_dict), ApiFriendList) as ApiFriendList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "friends: %s, " % [_friends]
		return output

# A group in the server.
class ApiGroup extends NakamaAsyncResult:

	const _SCHEMA = {
		"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"creator_id": {"name": "_creator_id", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
		"max_count": {"name": "_max_count", "type": TYPE_INT, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
	}

	# A URL for an avatar image.
	var _avatar_url
	var avatar_url : String:
		get:
			return "" if not _avatar_url is String else String(_avatar_url)

	# The UNIX time when the group was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The id of the user who created the group.
	var _creator_id
	var creator_id : String:
		get:
			return "" if not _creator_id is String else String(_creator_id)

	# A description for the group.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)

	# The current count of all members in the group.
	var _edge_count
	var edge_count : int:
		get:
			return 0 if not _edge_count is int else int(_edge_count)

	# The id of a group.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# The language expected to be a tag which follows the BCP-47 spec.
	var _lang_tag
	var lang_tag : String:
		get:
			return "" if not _lang_tag is String else String(_lang_tag)

	# The maximum number of members allowed.
	var _max_count
	var max_count : int:
		get:
			return 0 if not _max_count is int else int(_max_count)

	# Additional information stored as a JSON object.
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# The unique name of the group.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)

	# Anyone can join open groups, otherwise only admins can accept members.
	var _open
	var open : bool:
		get:
			return false if not _open is bool else bool(_open)

	# The UNIX time when the group was last updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroup:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroup", p_dict), ApiGroup) as ApiGroup

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "avatar_url: %s, " % _avatar_url
		output += "create_time: %s, " % _create_time
		output += "creator_id: %s, " % _creator_id
		output += "description: %s, " % _description
		output += "edge_count: %s, " % _edge_count
		output += "id: %s, " % _id
		output += "lang_tag: %s, " % _lang_tag
		output += "max_count: %s, " % _max_count
		output += "metadata: %s, " % _metadata
		output += "name: %s, " % _name
		output += "open: %s, " % _open
		output += "update_time: %s, " % _update_time
		return output

# One or more groups returned from a listing operation.
class ApiGroupList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"groups": {"name": "_groups", "type": TYPE_ARRAY, "required": false, "content": "ApiGroup"},
	}

	# A cursor used to get the next page.
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# One or more groups.
	var _groups
	var groups : Array:
		get:
			return Array() if not _groups is Array else Array(_groups)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupList", p_dict), ApiGroupList) as ApiGroupList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "groups: %s, " % [_groups]
		return output

# A list of users belonging to a group, along with their role.
class ApiGroupUserList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"group_users": {"name": "_group_users", "type": TYPE_ARRAY, "required": false, "content": "GroupUserListGroupUser"},
	}

	# Cursor for the next page of results, if any.
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# User-role pairs for a group.
	var _group_users
	var group_users : Array:
		get:
			return Array() if not _group_users is Array else Array(_group_users)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupUserList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupUserList", p_dict), ApiGroupUserList) as ApiGroupUserList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "group_users: %s, " % [_group_users]
		return output

# Represents a complete leaderboard record with all scores and associated metadata.
class ApiLeaderboardRecord extends NakamaAsyncResult:

	const _SCHEMA = {
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"expiry_time": {"name": "_expiry_time", "type": TYPE_STRING, "required": false},
		"leaderboard_id": {"name": "_leaderboard_id", "type": TYPE_STRING, "required": false},
		"max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"num_score": {"name": "_num_score", "type": TYPE_INT, "required": false},
		"owner_id": {"name": "_owner_id", "type": TYPE_STRING, "required": false},
		"rank": {"name": "_rank", "type": TYPE_STRING, "required": false},
		"score": {"name": "_score", "type": TYPE_STRING, "required": false},
		"subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
		"username": {"name": "_username", "type": TYPE_STRING, "required": false},
	}

	# The UNIX time when the leaderboard record was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The UNIX time when the leaderboard record expires.
	var _expiry_time
	var expiry_time : String:
		get:
			return "" if not _expiry_time is String else String(_expiry_time)

	# The ID of the leaderboard this score belongs to.
	var _leaderboard_id
	var leaderboard_id : String:
		get:
			return "" if not _leaderboard_id is String else String(_leaderboard_id)

	# The maximum number of score updates allowed by the owner.
	var _max_num_score
	var max_num_score : int:
		get:
			return 0 if not _max_num_score is int else int(_max_num_score)

	# Metadata.
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# The number of submissions to this score record.
	var _num_score
	var num_score : int:
		get:
			return 0 if not _num_score is int else int(_num_score)

	# The ID of the score owner, usually a user or group.
	var _owner_id
	var owner_id : String:
		get:
			return "" if not _owner_id is String else String(_owner_id)

	# The rank of this record.
	var _rank
	var rank : String:
		get:
			return "" if not _rank is String else String(_rank)

	# The score value.
	var _score
	var score : String:
		get:
			return "" if not _score is String else String(_score)

	# An optional subscore value.
	var _subscore
	var subscore : String:
		get:
			return "" if not _subscore is String else String(_subscore)

	# The UNIX time when the leaderboard record was updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	# The username of the score owner, if the owner is a user.
	var _username
	var username : String:
		get:
			return "" if not _username is String else String(_username)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecord:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecord", p_dict), ApiLeaderboardRecord) as ApiLeaderboardRecord

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "create_time: %s, " % _create_time
		output += "expiry_time: %s, " % _expiry_time
		output += "leaderboard_id: %s, " % _leaderboard_id
		output += "max_num_score: %s, " % _max_num_score
		output += "metadata: %s, " % _metadata
		output += "num_score: %s, " % _num_score
		output += "owner_id: %s, " % _owner_id
		output += "rank: %s, " % _rank
		output += "score: %s, " % _score
		output += "subscore: %s, " % _subscore
		output += "update_time: %s, " % _update_time
		output += "username: %s, " % _username
		return output

# A set of leaderboard records, may be part of a leaderboard records page or a batch of individual records.
class ApiLeaderboardRecordList extends NakamaAsyncResult:

	const _SCHEMA = {
		"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
		"owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
		"records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
	}

	# The cursor to send when retrieving the next page, if any.
	var _next_cursor
	var next_cursor : String:
		get:
			return "" if not _next_cursor is String else String(_next_cursor)

	# A batched set of leaderboard records belonging to specified owners.
	var _owner_records
	var owner_records : Array:
		get:
			return Array() if not _owner_records is Array else Array(_owner_records)

	# The cursor to send when retrieving the previous page, if any.
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	# A list of leaderboard records.
	var _records
	var records : Array:
		get:
			return Array() if not _records is Array else Array(_records)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecordList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecordList", p_dict), ApiLeaderboardRecordList) as ApiLeaderboardRecordList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "next_cursor: %s, " % _next_cursor
		output += "owner_records: %s, " % [_owner_records]
		output += "prev_cursor: %s, " % _prev_cursor
		output += "records: %s, " % [_records]
		return output

# Link Steam to the current user's account.
class ApiLinkSteamRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"account": {"name": "_account", "type": "ApiAccountSteam", "required": false},
		"sync": {"name": "_sync", "type": TYPE_BOOL, "required": false},
	}

	# The Facebook account details.
	var _account
	var account : ApiAccountSteam:
		get:
			return _account as ApiAccountSteam

	# Import Steam friends for the user.
	var _sync
	var sync : bool:
		get:
			return false if not _sync is bool else bool(_sync)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLinkSteamRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLinkSteamRequest", p_dict), ApiLinkSteamRequest) as ApiLinkSteamRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "account: %s, " % _account
		output += "sync: %s, " % _sync
		return output

# List user subscriptions.
class ApiListSubscriptionsRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"limit": {"name": "_limit", "type": TYPE_INT, "required": false},
	}

	#
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	#
	var _limit
	var limit : int:
		get:
			return 0 if not _limit is int else int(_limit)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiListSubscriptionsRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiListSubscriptionsRequest", p_dict), ApiListSubscriptionsRequest) as ApiListSubscriptionsRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "limit: %s, " % _limit
		return output

# Represents a realtime match.
class ApiMatch extends NakamaAsyncResult:

	const _SCHEMA = {
		"authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false},
		"handler_name": {"name": "_handler_name", "type": TYPE_STRING, "required": false},
		"label": {"name": "_label", "type": TYPE_STRING, "required": false},
		"match_id": {"name": "_match_id", "type": TYPE_STRING, "required": false},
		"size": {"name": "_size", "type": TYPE_INT, "required": false},
		"tick_rate": {"name": "_tick_rate", "type": TYPE_INT, "required": false},
	}

	# True if it's an server-managed authoritative match, false otherwise.
	var _authoritative
	var authoritative : bool:
		get:
			return false if not _authoritative is bool else bool(_authoritative)

	#
	var _handler_name
	var handler_name : String:
		get:
			return "" if not _handler_name is String else String(_handler_name)

	# Match label, if any.
	var _label
	var label : String:
		get:
			return "" if not _label is String else String(_label)

	# The ID of the match, can be used to join.
	var _match_id
	var match_id : String:
		get:
			return "" if not _match_id is String else String(_match_id)

	# Current number of users in the match.
	var _size
	var size : int:
		get:
			return 0 if not _size is int else int(_size)

	#
	var _tick_rate
	var tick_rate : int:
		get:
			return 0 if not _tick_rate is int else int(_tick_rate)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatch:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatch", p_dict), ApiMatch) as ApiMatch

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "authoritative: %s, " % _authoritative
		output += "handler_name: %s, " % _handler_name
		output += "label: %s, " % _label
		output += "match_id: %s, " % _match_id
		output += "size: %s, " % _size
		output += "tick_rate: %s, " % _tick_rate
		return output

# A list of realtime matches.
class ApiMatchList extends NakamaAsyncResult:

	const _SCHEMA = {
		"matches": {"name": "_matches", "type": TYPE_ARRAY, "required": false, "content": "ApiMatch"},
	}

	# A number of matches corresponding to a list operation.
	var _matches
	var matches : Array:
		get:
			return Array() if not _matches is Array else Array(_matches)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatchList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatchList", p_dict), ApiMatchList) as ApiMatchList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "matches: %s, " % [_matches]
		return output

# A notification in the server.
class ApiNotification extends NakamaAsyncResult:

	const _SCHEMA = {
		"code": {"name": "_code", "type": TYPE_INT, "required": false},
		"content": {"name": "_content", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false},
		"sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false},
		"subject": {"name": "_subject", "type": TYPE_STRING, "required": false},
	}

	# Category code for this notification.
	var _code
	var code : int:
		get:
			return 0 if not _code is int else int(_code)

	# Content of the notification in JSON.
	var _content
	var content : String:
		get:
			return "" if not _content is String else String(_content)

	# The UNIX time when the notification was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# ID of the Notification.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# True if this notification was persisted to the database.
	var _persistent
	var persistent : bool:
		get:
			return false if not _persistent is bool else bool(_persistent)

	# ID of the sender, if a user. Otherwise 'null'.
	var _sender_id
	var sender_id : String:
		get:
			return "" if not _sender_id is String else String(_sender_id)

	# Subject of the notification.
	var _subject
	var subject : String:
		get:
			return "" if not _subject is String else String(_subject)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotification:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotification", p_dict), ApiNotification) as ApiNotification

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "code: %s, " % _code
		output += "content: %s, " % _content
		output += "create_time: %s, " % _create_time
		output += "id: %s, " % _id
		output += "persistent: %s, " % _persistent
		output += "sender_id: %s, " % _sender_id
		output += "subject: %s, " % _subject
		return output

# A collection of zero or more notifications.
class ApiNotificationList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
		"notifications": {"name": "_notifications", "type": TYPE_ARRAY, "required": false, "content": "ApiNotification"},
	}

	# Use this cursor to paginate notifications. Cache this to catch up to new notifications.
	var _cacheable_cursor
	var cacheable_cursor : String:
		get:
			return "" if not _cacheable_cursor is String else String(_cacheable_cursor)

	# Collection of notifications.
	var _notifications
	var notifications : Array:
		get:
			return Array() if not _notifications is Array else Array(_notifications)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotificationList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotificationList", p_dict), ApiNotificationList) as ApiNotificationList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cacheable_cursor: %s, " % _cacheable_cursor
		output += "notifications: %s, " % [_notifications]
		return output

# Operator that can be used to override the one set in the leaderboard.
#  - NO_OVERRIDE: Do not override the leaderboard operator.
#  - BEST: Override the leaderboard operator with BEST.
#  - SET: Override the leaderboard operator with SET.
#  - INCREMENT: Override the leaderboard operator with INCREMENT.
#  - DECREMENT: Override the leaderboard operator with DECREMENT.# [ - NO_OVERRIDE: Do not override the leaderboard operator.  - BEST: Override the leaderboard operator with BEST.  - SET: Override the leaderboard operator with SET.  - INCREMENT: Override the leaderboard operator with INCREMENT.  - DECREMENT: Override the leaderboard operator with DECREMENT.]
enum ApiOperator {NO_OVERRIDE = 0,BEST = 1,SET = 2,INCREMENT = 3,DECREMENT = 4,}

# Storage objects to get.
class ApiReadStorageObjectId extends NakamaAsyncResult:

	const _SCHEMA = {
		"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
		"key": {"name": "_key", "type": TYPE_STRING, "required": false},
		"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
	}

	# The collection which stores the object.
	var _collection
	var collection : String:
		get:
			return "" if not _collection is String else String(_collection)

	# The key of the object within the collection.
	var _key
	var key : String:
		get:
			return "" if not _key is String else String(_key)

	# The user owner of the object.
	var _user_id
	var user_id : String:
		get:
			return "" if not _user_id is String else String(_user_id)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectId:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectId", p_dict), ApiReadStorageObjectId) as ApiReadStorageObjectId

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "collection: %s, " % _collection
		output += "key: %s, " % _key
		output += "user_id: %s, " % _user_id
		return output

# Batch get storage objects.
class ApiReadStorageObjectsRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiReadStorageObjectId"},
	}

	# Batch of storage objects.
	var _object_ids
	var object_ids : Array:
		get:
			return Array() if not _object_ids is Array else Array(_object_ids)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectsRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectsRequest", p_dict), ApiReadStorageObjectsRequest) as ApiReadStorageObjectsRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "object_ids: %s, " % [_object_ids]
		return output

# Execute an Lua function on the server.
class ApiRpc extends NakamaAsyncResult:

	const _SCHEMA = {
		"http_key": {"name": "_http_key", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"payload": {"name": "_payload", "type": TYPE_STRING, "required": false},
	}

	# The authentication key used when executed as a non-client HTTP request.
	var _http_key
	var http_key : String:
		get:
			return "" if not _http_key is String else String(_http_key)

	# The identifier of the function.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# The payload of the function which must be a JSON object.
	var _payload
	var payload : String:
		get:
			return "" if not _payload is String else String(_payload)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiRpc:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiRpc", p_dict), ApiRpc) as ApiRpc

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "http_key: %s, " % _http_key
		output += "id: %s, " % _id
		output += "payload: %s, " % _payload
		return output

# A user's session used to authenticate messages.
class ApiSession extends NakamaAsyncResult:

	const _SCHEMA = {
		"created": {"name": "_created", "type": TYPE_BOOL, "required": false},
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}

	# True if the corresponding account was just created, false otherwise.
	var _created
	var created : bool:
		get:
			return false if not _created is bool else bool(_created)

	# Refresh token that can be used for session token renewal.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)

	# Authentication credentials.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "created: %s, " % _created
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		return output

# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
class ApiSessionLogoutRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}

	# Refresh token to invalidate.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)

	# Session token to log out.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionLogoutRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionLogoutRequest", p_dict), ApiSessionLogoutRequest) as ApiSessionLogoutRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		return output

# Authenticate against the server with a refresh token.
class ApiSessionRefreshRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
		"vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}

	# Refresh token.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	# Extra information that will be bundled in the session token.
	var _vars
	var vars : Dictionary:
		get:
			return Dictionary() if not _vars is Dictionary else _vars.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionRefreshRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionRefreshRequest", p_dict), ApiSessionRefreshRequest) as ApiSessionRefreshRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "token: %s, " % _token
		var map_string : String = ""
		if typeof(_vars) == TYPE_DICTIONARY:
			for k in _vars:
				map_string += "{%s=%s}, " % [k, _vars[k]]
		output += "vars: [%s], " % map_string
		return output

# An object within the storage engine.
class ApiStorageObject extends NakamaAsyncResult:

	const _SCHEMA = {
		"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"key": {"name": "_key", "type": TYPE_STRING, "required": false},
		"permission_read": {"name": "_permission_read", "type": TYPE_INT, "required": false},
		"permission_write": {"name": "_permission_write", "type": TYPE_INT, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
		"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
		"version": {"name": "_version", "type": TYPE_STRING, "required": false},
	}

	# The collection which stores the object.
	var _collection
	var collection : String:
		get:
			return "" if not _collection is String else String(_collection)

	# The UNIX time when the object was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The key of the object within the collection.
	var _key
	var key : String:
		get:
			return "" if not _key is String else String(_key)

	# The read access permissions for the object.
	var _permission_read
	var permission_read : int:
		get:
			return 0 if not _permission_read is int else int(_permission_read)

	# The write access permissions for the object.
	var _permission_write
	var permission_write : int:
		get:
			return 0 if not _permission_write is int else int(_permission_write)

	# The UNIX time when the object was last updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	# The user owner of the object.
	var _user_id
	var user_id : String:
		get:
			return "" if not _user_id is String else String(_user_id)

	# The value of the object.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	# The version hash of the object.
	var _version
	var version : String:
		get:
			return "" if not _version is String else String(_version)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObject:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObject", p_dict), ApiStorageObject) as ApiStorageObject

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "collection: %s, " % _collection
		output += "create_time: %s, " % _create_time
		output += "key: %s, " % _key
		output += "permission_read: %s, " % _permission_read
		output += "permission_write: %s, " % _permission_write
		output += "update_time: %s, " % _update_time
		output += "user_id: %s, " % _user_id
		output += "value: %s, " % _value
		output += "version: %s, " % _version
		return output

# A storage acknowledgement.
class ApiStorageObjectAck extends NakamaAsyncResult:

	const _SCHEMA = {
		"collection": {"name": "_collection", "type": TYPE_STRING, "required": false},
		"key": {"name": "_key", "type": TYPE_STRING, "required": false},
		"user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false},
		"version": {"name": "_version", "type": TYPE_STRING, "required": false},
	}

	# The collection which stores the object.
	var _collection
	var collection : String:
		get:
			return "" if not _collection is String else String(_collection)

	# The key of the object within the collection.
	var _key
	var key : String:
		get:
			return "" if not _key is String else String(_key)

	# The owner of the object.
	var _user_id
	var user_id : String:
		get:
			return "" if not _user_id is String else String(_user_id)

	# The version hash of the object.
	var _version
	var version : String:
		get:
			return "" if not _version is String else String(_version)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAck:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAck", p_dict), ApiStorageObjectAck) as ApiStorageObjectAck

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "collection: %s, " % _collection
		output += "key: %s, " % _key
		output += "user_id: %s, " % _user_id
		output += "version: %s, " % _version
		return output

# Batch of acknowledgements for the storage object write.
class ApiStorageObjectAcks extends NakamaAsyncResult:

	const _SCHEMA = {
		"acks": {"name": "_acks", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObjectAck"},
	}

	# Batch of storage write acknowledgements.
	var _acks
	var acks : Array:
		get:
			return Array() if not _acks is Array else Array(_acks)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAcks:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAcks", p_dict), ApiStorageObjectAcks) as ApiStorageObjectAcks

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "acks: %s, " % [_acks]
		return output

# List of storage objects.
class ApiStorageObjectList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"},
	}

	# The cursor for the next page of results, if any.
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# The list of storage objects.
	var _objects
	var objects : Array:
		get:
			return Array() if not _objects is Array else Array(_objects)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectList", p_dict), ApiStorageObjectList) as ApiStorageObjectList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "objects: %s, " % [_objects]
		return output

# Batch of storage objects.
class ApiStorageObjects extends NakamaAsyncResult:

	const _SCHEMA = {
		"objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"},
	}

	# The batch of storage objects.
	var _objects
	var objects : Array:
		get:
			return Array() if not _objects is Array else Array(_objects)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjects:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjects", p_dict), ApiStorageObjects) as ApiStorageObjects

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "objects: %s, " % [_objects]
		return output

# Environment where a purchase/subscription took place,
# - UNKNOWN: Unknown environment.
#  - SANDBOX: Sandbox/test environment.
#  - PRODUCTION: Production environment.# [- UNKNOWN: Unknown environment.  - SANDBOX: Sandbox/test environment.  - PRODUCTION: Production environment.]
enum ApiStoreEnvironment {UNKNOWN = 0,SANDBOX = 1,PRODUCTION = 2,}

# Validation Provider,
# - APPLE_APP_STORE: Apple App Store
#  - GOOGLE_PLAY_STORE: Google Play Store
#  - HUAWEI_APP_GALLERY: Huawei App Gallery# [- APPLE_APP_STORE: Apple App Store  - GOOGLE_PLAY_STORE: Google Play Store  - HUAWEI_APP_GALLERY: Huawei App Gallery]
enum ApiStoreProvider {APPLE_APP_STORE = 0,GOOGLE_PLAY_STORE = 1,HUAWEI_APP_GALLERY = 2,}

# A list of validated subscriptions stored by Nakama.
class ApiSubscriptionList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
		"validated_subscriptions": {"name": "_validated_subscriptions", "type": TYPE_ARRAY, "required": false, "content": "ApiValidatedSubscription"},
	}

	# The cursor to send when retrieving the next page, if any.
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# The cursor to send when retrieving the previous page, if any.
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	# Stored validated subscriptions.
	var _validated_subscriptions
	var validated_subscriptions : Array:
		get:
			return Array() if not _validated_subscriptions is Array else Array(_validated_subscriptions)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSubscriptionList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSubscriptionList", p_dict), ApiSubscriptionList) as ApiSubscriptionList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "prev_cursor: %s, " % _prev_cursor
		output += "validated_subscriptions: %s, " % [_validated_subscriptions]
		return output

# A tournament on the server.
class ApiTournament extends NakamaAsyncResult:

	const _SCHEMA = {
		"authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false},
		"can_enter": {"name": "_can_enter", "type": TYPE_BOOL, "required": false},
		"category": {"name": "_category", "type": TYPE_INT, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"duration": {"name": "_duration", "type": TYPE_INT, "required": false},
		"end_active": {"name": "_end_active", "type": TYPE_INT, "required": false},
		"end_time": {"name": "_end_time", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false},
		"max_size": {"name": "_max_size", "type": TYPE_INT, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"next_reset": {"name": "_next_reset", "type": TYPE_INT, "required": false},
		"operator": {"name": "_operator", "type": TYPE_INT, "required": false},
		"prev_reset": {"name": "_prev_reset", "type": TYPE_INT, "required": false},
		"size": {"name": "_size", "type": TYPE_INT, "required": false},
		"sort_order": {"name": "_sort_order", "type": TYPE_INT, "required": false},
		"start_active": {"name": "_start_active", "type": TYPE_INT, "required": false},
		"start_time": {"name": "_start_time", "type": TYPE_STRING, "required": false},
		"title": {"name": "_title", "type": TYPE_STRING, "required": false},
	}

	# Whether the leaderboard was created authoritatively or not.
	var _authoritative
	var authoritative : bool:
		get:
			return false if not _authoritative is bool else bool(_authoritative)

	# True if the tournament is active and can enter. A computed value.
	var _can_enter
	var can_enter : bool:
		get:
			return false if not _can_enter is bool else bool(_can_enter)

	# The category of the tournament. e.g. "vip" could be category 1.
	var _category
	var category : int:
		get:
			return 0 if not _category is int else int(_category)

	# The UNIX time when the tournament was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The description of the tournament. May be blank.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)

	# Duration of the tournament in seconds.
	var _duration
	var duration : int:
		get:
			return 0 if not _duration is int else int(_duration)

	# The UNIX time when the tournament stops being active until next reset. A computed value.
	var _end_active
	var end_active : int:
		get:
			return 0 if not _end_active is int else int(_end_active)

	# The UNIX time when the tournament will be stopped.
	var _end_time
	var end_time : String:
		get:
			return "" if not _end_time is String else String(_end_time)

	# The ID of the tournament.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# The maximum score updates allowed per player for the current tournament.
	var _max_num_score
	var max_num_score : int:
		get:
			return 0 if not _max_num_score is int else int(_max_num_score)

	# The maximum number of players for the tournament.
	var _max_size
	var max_size : int:
		get:
			return 0 if not _max_size is int else int(_max_size)

	# Additional information stored as a JSON object.
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# The UNIX time when the tournament is next playable. A computed value.
	var _next_reset
	var next_reset : int:
		get:
			return 0 if not _next_reset is int else int(_next_reset)

	# Operator.
	var _operator
	var operator : int:
		get:
			return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator

	# The UNIX time when the tournament was last reset. A computed value.
	var _prev_reset
	var prev_reset : int:
		get:
			return 0 if not _prev_reset is int else int(_prev_reset)

	# The current number of players in the tournament.
	var _size
	var size : int:
		get:
			return 0 if not _size is int else int(_size)

	# ASC (0) or DESC (1) sort mode of scores in the tournament.
	var _sort_order
	var sort_order : int:
		get:
			return 0 if not _sort_order is int else int(_sort_order)

	# The UNIX time when the tournament start being active. A computed value.
	var _start_active
	var start_active : int:
		get:
			return 0 if not _start_active is int else int(_start_active)

	# The UNIX time when the tournament will start.
	var _start_time
	var start_time : String:
		get:
			return "" if not _start_time is String else String(_start_time)

	# The title for the tournament.
	var _title
	var title : String:
		get:
			return "" if not _title is String else String(_title)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournament:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournament", p_dict), ApiTournament) as ApiTournament

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "authoritative: %s, " % _authoritative
		output += "can_enter: %s, " % _can_enter
		output += "category: %s, " % _category
		output += "create_time: %s, " % _create_time
		output += "description: %s, " % _description
		output += "duration: %s, " % _duration
		output += "end_active: %s, " % _end_active
		output += "end_time: %s, " % _end_time
		output += "id: %s, " % _id
		output += "max_num_score: %s, " % _max_num_score
		output += "max_size: %s, " % _max_size
		output += "metadata: %s, " % _metadata
		output += "next_reset: %s, " % _next_reset
		output += "operator: %s, " % _operator
		output += "prev_reset: %s, " % _prev_reset
		output += "size: %s, " % _size
		output += "sort_order: %s, " % _sort_order
		output += "start_active: %s, " % _start_active
		output += "start_time: %s, " % _start_time
		output += "title: %s, " % _title
		return output

# A list of tournaments.
class ApiTournamentList extends NakamaAsyncResult:

	const _SCHEMA = {
		"cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false},
		"tournaments": {"name": "_tournaments", "type": TYPE_ARRAY, "required": false, "content": "ApiTournament"},
	}

	# A pagination cursor (optional).
	var _cursor
	var cursor : String:
		get:
			return "" if not _cursor is String else String(_cursor)

	# The list of tournaments returned.
	var _tournaments
	var tournaments : Array:
		get:
			return Array() if not _tournaments is Array else Array(_tournaments)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentList", p_dict), ApiTournamentList) as ApiTournamentList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "cursor: %s, " % _cursor
		output += "tournaments: %s, " % [_tournaments]
		return output

# A set of tournament records which may be part of a tournament records page or a batch of individual records.
class ApiTournamentRecordList extends NakamaAsyncResult:

	const _SCHEMA = {
		"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
		"owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
		"records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"},
	}

	# The cursor to send when retireving the next page (optional).
	var _next_cursor
	var next_cursor : String:
		get:
			return "" if not _next_cursor is String else String(_next_cursor)

	# A batched set of tournament records belonging to specified owners.
	var _owner_records
	var owner_records : Array:
		get:
			return Array() if not _owner_records is Array else Array(_owner_records)

	# The cursor to send when retrieving the previous page (optional).
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	# A list of tournament records.
	var _records
	var records : Array:
		get:
			return Array() if not _records is Array else Array(_records)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentRecordList:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentRecordList", p_dict), ApiTournamentRecordList) as ApiTournamentRecordList

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "next_cursor: %s, " % _next_cursor
		output += "owner_records: %s, " % [_owner_records]
		output += "prev_cursor: %s, " % _prev_cursor
		output += "records: %s, " % [_records]
		return output

# Update a user's account details.
class ApiUpdateAccountRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
		"display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false},
		"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
		"location": {"name": "_location", "type": TYPE_STRING, "required": false},
		"timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false},
		"username": {"name": "_username", "type": TYPE_STRING, "required": false},
	}

	# A URL for an avatar image.
	var _avatar_url
	var avatar_url : String:
		get:
			return "" if not _avatar_url is String else String(_avatar_url)

	# The display name of the user.
	var _display_name
	var display_name : String:
		get:
			return "" if not _display_name is String else String(_display_name)

	# The language expected to be a tag which follows the BCP-47 spec.
	var _lang_tag
	var lang_tag : String:
		get:
			return "" if not _lang_tag is String else String(_lang_tag)

	# The location set by the user.
	var _location
	var location : String:
		get:
			return "" if not _location is String else String(_location)

	# The timezone set by the user.
	var _timezone
	var timezone : String:
		get:
			return "" if not _timezone is String else String(_timezone)

	# The username of the user's account.
	var _username
	var username : String:
		get:
			return "" if not _username is String else String(_username)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateAccountRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateAccountRequest", p_dict), ApiUpdateAccountRequest) as ApiUpdateAccountRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "avatar_url: %s, " % _avatar_url
		output += "display_name: %s, " % _display_name
		output += "lang_tag: %s, " % _lang_tag
		output += "location: %s, " % _location
		output += "timezone: %s, " % _timezone
		output += "username: %s, " % _username
		return output

# Update fields in a given group.
class ApiUpdateGroupRequest extends NakamaAsyncResult:

	const _SCHEMA = {
		"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false},
		"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"open": {"name": "_open", "type": TYPE_BOOL, "required": false},
	}

	# Avatar URL.
	var _avatar_url
	var avatar_url : String:
		get:
			return "" if not _avatar_url is String else String(_avatar_url)

	# Description string.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)

	# The ID of the group to update.
	var _group_id
	var group_id : String:
		get:
			return "" if not _group_id is String else String(_group_id)

	# Lang tag.
	var _lang_tag
	var lang_tag : String:
		get:
			return "" if not _lang_tag is String else String(_lang_tag)

	# Name.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)

	# Open is true if anyone should be allowed to join, or false if joins must be approved by a group admin.
	var _open
	var open : bool:
		get:
			return false if not _open is bool else bool(_open)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateGroupRequest:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateGroupRequest", p_dict), ApiUpdateGroupRequest) as ApiUpdateGroupRequest

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "avatar_url: %s, " % _avatar_url
		output += "description: %s, " % _description
		output += "group_id: %s, " % _group_id
		output += "lang_tag: %s, " % _lang_tag
		output += "name: %s, " % _name
		output += "open: %s, " % _open
		return output

# A user in the server.
class ApiUser extends NakamaAsyncResult:

	const _SCHEMA = {
		"apple_id": {"name": "_apple_id", "type": TYPE_STRING, "required": false},
		"avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false},
		"edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false},
		"facebook_id": {"name": "_facebook_id", "type": TYPE_STRING, "required": false},
		"facebook_instant_game_id": {"name": "_facebook_instant_game_id", "type": TYPE_STRING, "required": false},
		"gamecenter_id": {"name": "_gamecenter_id", "type": TYPE_STRING, "required": false},
		"google_id": {"name": "_google_id", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false},
		"location": {"name": "_location", "type": TYPE_STRING, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false},
		"online": {"name": "_online", "type": TYPE_BOOL, "required": false},
		"steam_id": {"name": "_steam_id", "type": TYPE_STRING, "required": false},
		"timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
		"username": {"name": "_username", "type": TYPE_STRING, "required": false},
	}

	# The Apple Sign In ID in the user's account.
	var _apple_id
	var apple_id : String:
		get:
			return "" if not _apple_id is String else String(_apple_id)

	# A URL for an avatar image.
	var _avatar_url
	var avatar_url : String:
		get:
			return "" if not _avatar_url is String else String(_avatar_url)

	# The UNIX time when the user was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)

	# The display name of the user.
	var _display_name
	var display_name : String:
		get:
			return "" if not _display_name is String else String(_display_name)

	# Number of related edges to this user.
	var _edge_count
	var edge_count : int:
		get:
			return 0 if not _edge_count is int else int(_edge_count)

	# The Facebook id in the user's account.
	var _facebook_id
	var facebook_id : String:
		get:
			return "" if not _facebook_id is String else String(_facebook_id)

	# The Facebook Instant Game ID in the user's account.
	var _facebook_instant_game_id
	var facebook_instant_game_id : String:
		get:
			return "" if not _facebook_instant_game_id is String else String(_facebook_instant_game_id)

	# The Apple Game Center in of the user's account.
	var _gamecenter_id
	var gamecenter_id : String:
		get:
			return "" if not _gamecenter_id is String else String(_gamecenter_id)

	# The Google id in the user's account.
	var _google_id
	var google_id : String:
		get:
			return "" if not _google_id is String else String(_google_id)

	# The id of the user's account.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	# The language expected to be a tag which follows the BCP-47 spec.
	var _lang_tag
	var lang_tag : String:
		get:
			return "" if not _lang_tag is String else String(_lang_tag)

	# The location set by the user.
	var _location
	var location : String:
		get:
			return "" if not _location is String else String(_location)

	# Additional information stored as a JSON object.
	var _metadata
	var metadata : String:
		get:
			return "" if not _metadata is String else String(_metadata)

	# Indicates whether the user is currently online.
	var _online
	var online : bool:
		get:
			return false if not _online is bool else bool(_online)

	# The Steam id in the user's account.
	var _steam_id
	var steam_id : String:
		get:
			return "" if not _steam_id is String else String(_steam_id)

	# The timezone set by the user.
	var _timezone
	var timezone : String:
		get:
			return "" if not _timezone is String else String(_timezone)

	# The UNIX time when the user was last updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	# The username of the user's account.
	var _username
	var username : String:
		get:
			return "" if not _username is String else String(_username)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUser:
		return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUser", p_dict), ApiUser) as ApiUser

	func serialize() -> Dictionary:
		return NakamaSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		output += "apple_id: %s, " % _apple_id
		output += "avatar_url: %s, " % _avatar_url
		output += "create_time: %s, " % _create_time
		output += "display_name: %s, " % _display_name
		output += "edge_count: %s, " % _edge_count
		output += "facebook_id: %s, " % _facebook_id
		output += "facebook_instant_game_id: %s, " % _facebook_instant_game_id
		output += "gamecenter_id: %s, " % _gamecenter_id
		output += "google_id: %s, " % _google_id
		output += "id: %s, " % _id
		output += "lang_tag: %s, " % _lang_tag
		output += "location: %s, " % _location
		output += "metadata: %s, " % _metadata
		output += "onli
Download .txt
gitextract_l9w5256r/

├── .github/
│   ├── CODEOWNERS
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── RCLONE.md
│   ├── TRANSLATING.md
│   └── workflows/
│       └── github-actions-youtd.yml
├── .gitignore
├── LICENSE
├── README.md
├── addons/
│   ├── com.heroiclabs.nakama/
│   │   ├── Nakama.gd
│   │   ├── Satori/
│   │   │   ├── NakamaEvent.gd
│   │   │   ├── SatoriAPI.gd
│   │   │   ├── SatoriClient.gd
│   │   │   ├── SatoriHttpAdapter.gd
│   │   │   ├── SatoriSession.gd
│   │   │   └── utils/
│   │   │       ├── SatoriAsyncResult.gd
│   │   │       ├── SatoriException.gd
│   │   │       ├── SatoriLogger.gd
│   │   │       └── SatoriSerializer.gd
│   │   ├── Satori.gd
│   │   ├── api/
│   │   │   ├── NakamaAPI.gd
│   │   │   ├── NakamaRTAPI.gd
│   │   │   ├── NakamaRTMessage.gd
│   │   │   ├── NakamaSession.gd
│   │   │   ├── NakamaStorageObjectId.gd
│   │   │   └── NakamaWriteStorageObject.gd
│   │   ├── client/
│   │   │   ├── NakamaClient.gd
│   │   │   └── NakamaHTTPAdapter.gd
│   │   ├── dotnet-utils/
│   │   │   ├── GodotHttpAdapter.cs
│   │   │   ├── GodotLogger.cs
│   │   │   └── GodotWebSocketAdapter.cs
│   │   ├── socket/
│   │   │   ├── NakamaSocket.gd
│   │   │   └── NakamaSocketAdapter.gd
│   │   └── utils/
│   │       ├── NakamaAsyncResult.gd
│   │       ├── NakamaException.gd
│   │       ├── NakamaLogger.gd
│   │       ├── NakamaMultiplayerBridge.gd
│   │       ├── NakamaMultiplayerPeer.gd
│   │       └── NakamaSerializer.gd
│   └── nakama-webrtc/
│       ├── LICENSE.txt
│       └── OnlineMatch.gd
├── assets/
│   ├── LICENSE.md
│   ├── README.md
│   ├── creeps/
│   │   ├── README.md
│   │   └── orc/
│   │       ├── air/
│   │       │   ├── fly_E.png.import
│   │       │   ├── fly_N.png.import
│   │       │   ├── fly_NE.png.import
│   │       │   ├── fly_NW.png.import
│   │       │   ├── fly_S.png.import
│   │       │   ├── fly_SE.png.import
│   │       │   ├── fly_SW.png.import
│   │       │   ├── fly_W.png.import
│   │       │   ├── metadata.csv
│   │       │   └── metadata.csv.import
│   │       ├── boss/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       ├── champion/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       ├── mass/
│   │       │   ├── death_E.png.import
│   │       │   ├── death_N.png.import
│   │       │   ├── death_S.png.import
│   │       │   ├── death_W.png.import
│   │       │   ├── metadata.csv
│   │       │   ├── metadata.csv.import
│   │       │   ├── slow_run_E.png.import
│   │       │   ├── slow_run_N.png.import
│   │       │   ├── slow_run_S.png.import
│   │       │   └── slow_run_W.png.import
│   │       └── normal/
│   │           ├── death_E.png.import
│   │           ├── death_N.png.import
│   │           ├── death_S.png.import
│   │           ├── death_W.png.import
│   │           ├── metadata.csv
│   │           ├── metadata.csv.import
│   │           ├── slow_run_E.png.import
│   │           ├── slow_run_N.png.import
│   │           ├── slow_run_S.png.import
│   │           └── slow_run_W.png.import
│   ├── effects/
│   │   ├── arrow.png.import
│   │   ├── bdragon/
│   │   │   ├── README.md
│   │   │   ├── ancient_protector_missile_293.png.import
│   │   │   ├── animated_dead_target_102.png.import
│   │   │   ├── apply_potion_537.png.import
│   │   │   ├── arcane_tower_attack_024.png.import
│   │   │   ├── avatar_caster_10.png.import
│   │   │   ├── banshee_missile_487.png.import
│   │   │   ├── blink_target_720.png.import
│   │   │   ├── blood_splatter_376.png.import
│   │   │   ├── build_tower_648.png.import
│   │   │   ├── charm_target_703.png.import
│   │   │   ├── cloud_of_fog_382.png.import
│   │   │   ├── cloud_of_fog_small_428.png.import
│   │   │   ├── cripple_target_198.png.import
│   │   │   ├── crushing_wave_damage_584.png.import
│   │   │   ├── crypt_fiend_eggsack_528.png.import
│   │   │   ├── cyclone_target_269.png.import
│   │   │   ├── death_and_decay_71.png.import
│   │   │   ├── death_coil_special_728.png.import
│   │   │   ├── devour_509.png.import
│   │   │   ├── dispel_magic_target_456.png.import
│   │   │   ├── doom_death_451.png.import
│   │   │   ├── faerie_dragon_missile_482.png.import
│   │   │   ├── firelord_death_explode_77.png.import
│   │   │   ├── flame_strike_embers_702.png.import
│   │   │   ├── flower_aura_655.png.import
│   │   │   ├── frag_boom_spawn_426.png.import
│   │   │   ├── freezing_breath_519.png.import
│   │   │   ├── frost_armor_damage_474.png.import
│   │   │   ├── frost_bolt_missile_063.png.import
│   │   │   ├── glaive_746.png.import
│   │   │   ├── gold_credit_673.png.import
│   │   │   ├── gold_credit_88.png.import
│   │   │   ├── healing_wave_target_453.png.import
│   │   │   ├── holy_bolt_241.png.import
│   │   │   ├── immolation_damage_541.png.import
│   │   │   ├── impale_hit_target_529.png.import
│   │   │   ├── impale_target_dust_025.png.import
│   │   │   ├── incinerate_76.png.import
│   │   │   ├── keeper_grove_missile_297.png.import
│   │   │   ├── level_up_455.png.import
│   │   │   ├── mana_burn_target_388.png.import
│   │   │   ├── mana_shield_026.png.import
│   │   │   ├── mass_teleport_caster_335.png.import
│   │   │   ├── mass_teleport_target_315.png.import
│   │   │   ├── mirror_image_caster_711.png.import
│   │   │   ├── moonwell_target_584.png.import
│   │   │   ├── ne_cancel_death_672.png.import
│   │   │   ├── ne_death_612.png.import
│   │   │   ├── placeholder_481.png.import
│   │   │   ├── polymorph_target_735.png.import
│   │   │   ├── projectile_explosion_299.png.import
│   │   │   ├── purge_buff_target_195.png.import
│   │   │   ├── quillspray_747.png.import
│   │   │   ├── raise_skeleton_624.png.import
│   │   │   ├── replenish_mana_334.png.import
│   │   │   ├── revive_human_623.png.import
│   │   │   ├── roar_506.png.import
│   │   │   ├── roots_235.png.import
│   │   │   ├── shackle_439.png.import
│   │   │   ├── shockwave_missile_440.png.import
│   │   │   ├── silence_area_611.png.import
│   │   │   ├── small_flame_spawn_240.png.import
│   │   │   ├── spell_aiil_452.png.import
│   │   │   ├── spell_ailb_723.png.import
│   │   │   ├── spell_aima_194.png.import
│   │   │   ├── spell_aire_174.png.import
│   │   │   ├── spell_aiso_295.png.import
│   │   │   ├── spell_alim_136.png.import
│   │   │   ├── spell_breaker_target_613.png.import
│   │   │   ├── spirit_link_target_175.png.import
│   │   │   ├── stampede_missile_death_63.png.import
│   │   │   ├── starfall_target_257.png.import
│   │   │   ├── thunder_clap_466.png.import
│   │   │   ├── undead_dissipate_633.png.import
│   │   │   ├── upgrade_tower_016.png.import
│   │   │   ├── vampiric_aura_199.png.import
│   │   │   ├── voodoo_aura_182.png.import
│   │   │   ├── warstomp_caster_536.png.import
│   │   │   ├── wind_shear_559.png.import
│   │   │   ├── wisp_explode_003.png.import
│   │   │   ├── ziggurat_frost_missile_325.png.import
│   │   │   └── zombify_target_274.png.import
│   │   ├── death_explode.png.import
│   │   ├── lightning_long.png.import
│   │   └── stun.png.import
│   ├── fonts/
│   │   ├── Friz Quadrata Std Medium.otf.import
│   │   └── NotoSansSC-Medium.ttf.import
│   ├── hud/
│   │   ├── bitmaps/
│   │   │   ├── circle_bitmap_100x100.png.import
│   │   │   └── circle_bitmap_256x256.png.import
│   │   ├── checkbox.png.import
│   │   ├── circle_bitmap_256x256.png.import
│   │   ├── darkness_face.png.import
│   │   ├── element_progress_circle.png.import
│   │   ├── horadric_cube.png.import
│   │   ├── hud_atlas.png.import
│   │   ├── misc2.png.import
│   │   ├── misc3.png.import
│   │   ├── misc3_s.png.import
│   │   ├── misc4.png.import
│   │   └── tranquility_face.png.import
│   ├── icons/
│   │   ├── amulets.png.import
│   │   ├── animals.png.import
│   │   ├── armor.png.import
│   │   ├── blunt_weapons.png.import
│   │   ├── books.png.import
│   │   ├── bows.png.import
│   │   ├── cannons.png.import
│   │   ├── clubs.png.import
│   │   ├── creep_icons_atlas.png.import
│   │   ├── daggers.png.import
│   │   ├── dioramas.png.import
│   │   ├── electricity.png.import
│   │   ├── elements.png.import
│   │   ├── faces.png.import
│   │   ├── fire.png.import
│   │   ├── food.png.import
│   │   ├── furniture.png.import
│   │   ├── gems.png.import
│   │   ├── generic_icons.png.import
│   │   ├── gloves.png.import
│   │   ├── helmets.png.import
│   │   ├── holy.png.import
│   │   ├── hud.png.import
│   │   ├── magic.png.import
│   │   ├── masks.png.import
│   │   ├── mechanical.png.import
│   │   ├── misc.png.import
│   │   ├── orbs.png.import
│   │   ├── plants.png.import
│   │   ├── potion_icons_m.png.import
│   │   ├── rings.png.import
│   │   ├── rockets.png.import
│   │   ├── scrolls.png.import
│   │   ├── shields.png.import
│   │   ├── spears.png.import
│   │   ├── statues.png.import
│   │   ├── staves.png.import
│   │   ├── swords.png.import
│   │   ├── tier_icons_m.png.import
│   │   ├── tower_icons_m.png.import
│   │   ├── tower_variations.png.import
│   │   ├── trinkets.png.import
│   │   ├── undead.png.import
│   │   └── weapons_misc.png.import
│   ├── misc/
│   │   ├── autocast_automode_particle.png.import
│   │   ├── cast_cursor.png.import
│   │   ├── circle_01.png.import
│   │   ├── circle_02.png.import
│   │   ├── circle_03.png.import
│   │   ├── circle_04.png.import
│   │   ├── circle_05.png.import
│   │   ├── creep_blood_pool.png.import
│   │   ├── icob_min.png.import
│   │   ├── icob_ultra_wide.png.import
│   │   ├── icon.png.import
│   │   ├── potion_drop_animation.png.import
│   │   └── projectile.png.import
│   ├── secrets/
│   │   ├── badwords.csv.import
│   │   └── secrets.csv.import
│   ├── sfx/
│   │   ├── 161654__qubodup__war-game-battle-level-up-remix.ogg.import
│   │   ├── 202147__qubodup__enchant.ogg.import
│   │   ├── 411177__silverillusionist__pick-up-item-1-short.ogg.import
│   │   ├── 420676__sypherzent__spell-cast-buff-high-tone.ogg.import
│   │   ├── 442827__qubodup__fireball.ogg.import
│   │   ├── 442903__qubodup__slash-remix.ogg.import
│   │   ├── 541478__eminyildirim__magic-fire-spell-impact-punch.ogg.import
│   │   ├── 562292__colorscrimsontears__heal-rpg.ogg.import
│   │   ├── 649359__sonofxaudio__sword_water01.ogg.import
│   │   ├── 665082__sunflora__thud.ogg.import
│   │   ├── 682635__bastianhallo__magic-spell.ogg.import
│   │   ├── 683044__brettrader__stomp-soft.ogg.import
│   │   ├── 714258__qubodup__cloud-poof.ogg.import
│   │   ├── 734247__noisyredfox__coins3.ogg.import
│   │   ├── 738438__qubodup__orc-grunt-2.ogg.import
│   │   ├── 745156__tigreplayz__blast-explosion.ogg.import
│   │   ├── DoKashiteru_healspell1.ogg.import
│   │   ├── DoKashiteru_healspell2.ogg.import
│   │   ├── DoKashiteru_healspell3.ogg.import
│   │   ├── README.md
│   │   ├── UI_Electric_01.ogg.import
│   │   ├── artisticdude_freeze.ogg.import
│   │   ├── attribution.csv
│   │   ├── attribution.csv.import
│   │   ├── bart_foom_0.ogg.import
│   │   ├── copyc4t_Archers-shooting.ogg.import
│   │   ├── kevl_level_up.ogg.import
│   │   ├── little_robot_Spell_00.ogg.import
│   │   ├── little_robot_Spell_01.ogg.import
│   │   ├── little_robot_UI_Electric_00.ogg.import
│   │   ├── little_robot_UI_Electric_01.ogg.import
│   │   ├── little_robot_Whoosh_Electric_00.ogg.import
│   │   ├── little_robot_Whoosh_Electric_01.ogg.import
│   │   ├── little_robot_Whoosh_Electric_02.ogg.import
│   │   ├── little_robot_Whoosh_Electric_03.ogg.import
│   │   ├── machel_baradari_jump.wav.import
│   │   ├── michel_baradari_jump.ogg.import
│   │   ├── michel_baradari_jump.wav.import
│   │   ├── michel_baradari_lava.ogg.import
│   │   ├── michel_baradari_teleport.ogg.import
│   │   ├── p0ss_confusion.ogg.import
│   │   ├── p0ss_curse5.ogg.import
│   │   ├── p0ss_enchant.ogg.import
│   │   ├── p0ss_enchant2.ogg.import
│   │   ├── p0ss_explode2.ogg.import
│   │   ├── p0ss_explode4.ogg.import
│   │   ├── p0ss_freeze2.ogg.import
│   │   ├── p0ss_heal.ogg.import
│   │   ├── p0ss_pestilence.ogg.import
│   │   ├── p0ss_sand.ogg.import
│   │   ├── p0ss_shot.ogg.import
│   │   ├── p0ss_spell.ogg.import
│   │   ├── p0ss_steam.ogg.import
│   │   ├── p0ss_teleport.ogg.import
│   │   ├── p0ss_warp.ogg.import
│   │   ├── p0ss_warp2.ogg.import
│   │   ├── p0ss_warp3.ogg.import
│   │   ├── p0ss_water.ogg.import
│   │   ├── p0ss_zap.ogg.import
│   │   ├── p0ss_zap10.ogg.import
│   │   ├── p0ss_zap5a.ogg.import
│   │   ├── spit_01.ogg.import
│   │   ├── unknown_attack_sound1.ogg.import
│   │   ├── unknown_fire_attack1.ogg.import
│   │   ├── unknown_iceball.ogg.import
│   │   ├── unknown_iron_attack1.ogg.import
│   │   ├── unknown_swosh-08.ogg.import
│   │   └── unknown_swosh-11.ogg.import
│   ├── texts/
│   │   ├── README.md
│   │   ├── texts.csv.import
│   │   ├── texts_history.csv
│   │   └── texts_history.csv.import
│   ├── tiles/
│   │   ├── License.txt
│   │   ├── README.md
│   │   ├── barrels.png.import
│   │   ├── bridges.png.import
│   │   ├── chairs.png.import
│   │   ├── chests.png.import
│   │   ├── empty_tiles.png.import
│   │   ├── floor.png.import
│   │   ├── floor1_walls.png.import
│   │   ├── planks.png.import
│   │   ├── spiral_stairs.png.import
│   │   ├── stairs.png.import
│   │   ├── stone_columns.png.import
│   │   ├── stone_walls.png.import
│   │   ├── tables.png.import
│   │   ├── wooden_pile.png.import
│   │   └── wooden_supports.png.import
│   ├── tiles_decoration/
│   │   ├── bushes1.png.import
│   │   ├── column_overgrown.png.import
│   │   ├── leaves1.png.import
│   │   ├── stones1.png.import
│   │   ├── stones2.png.import
│   │   ├── stones3.png.import
│   │   ├── trees1.png.import
│   │   ├── trees2.png.import
│   │   ├── vines1.png.import
│   │   ├── vines2.png.import
│   │   ├── vines3.png.import
│   │   ├── vines4.png.import
│   │   ├── vines5.png.import
│   │   ├── vines6.png.import
│   │   ├── vines7.png.import
│   │   └── wall_vines1.png.import
│   ├── tower_sprites/
│   │   ├── astral_common.png.import
│   │   ├── astral_rare.png.import
│   │   ├── astral_uncommon.png.import
│   │   ├── astral_unique.png.import
│   │   ├── darkness_common.png.import
│   │   ├── darkness_rare.png.import
│   │   ├── darkness_uncommon.png.import
│   │   ├── darkness_unique.png.import
│   │   ├── fire_common.png.import
│   │   ├── fire_rare.png.import
│   │   ├── fire_uncommon.png.import
│   │   ├── fire_unique.png.import
│   │   ├── ice_common.png.import
│   │   ├── ice_rare.png.import
│   │   ├── ice_uncommon.png.import
│   │   ├── ice_unique.png.import
│   │   ├── iron_common.png.import
│   │   ├── iron_rare.png.import
│   │   ├── iron_uncommon.png.import
│   │   ├── iron_unique.png.import
│   │   ├── nature_common.png.import
│   │   ├── nature_rare.png.import
│   │   ├── nature_uncommon.png.import
│   │   ├── nature_unique.png.import
│   │   ├── storm_common.png.import
│   │   ├── storm_rare.png.import
│   │   ├── storm_uncommon.png.import
│   │   └── storm_unique.png.import
│   └── tutorial_pictures/
│       ├── README.md
│       ├── build_tower.png.import
│       ├── item_drop.png.import
│       ├── research.png.import
│       ├── research_element.png.import
│       ├── resource_panel.png.import
│       ├── roll_towers.png.import
│       ├── tower_info.png.import
│       ├── tower_level.png.import
│       ├── tower_mouse_over.png.import
│       ├── tower_stash.png.import
│       ├── transform.png.import
│       ├── upgrade.png.import
│       └── wave_finish.png.import
├── build/
│   ├── README.md
│   ├── linux/
│   │   └── README.md
│   ├── macos/
│   │   └── README.md
│   ├── web/
│   │   └── full-size.html
│   └── windows/
│       └── README.md
├── data/
│   ├── README.md
│   ├── ability_properties.csv
│   ├── ability_properties.csv.import
│   ├── aura_properties.csv
│   ├── aura_properties.csv.import
│   ├── autocast_properties.csv
│   ├── autocast_properties.csv.import
│   ├── builder_properties.csv
│   ├── builder_properties.csv.import
│   ├── exp_for_level.csv
│   ├── exp_for_level.csv.import
│   ├── hints/
│   │   ├── advanced.csv
│   │   ├── advanced.csv.import
│   │   ├── basic.csv.import
│   │   ├── basics.csv
│   │   ├── basics.csv.import
│   │   ├── chat_commands.csv
│   │   ├── chat_commands.csv.import
│   │   ├── creep_specials.csv
│   │   ├── creep_specials.csv.import
│   │   ├── creeps.csv
│   │   ├── creeps.csv.import
│   │   ├── items.csv
│   │   ├── items.csv.import
│   │   ├── towers.csv
│   │   ├── towers.csv.import
│   │   ├── tutorial.csv
│   │   └── tutorial.csv.import
│   ├── item_properties.csv
│   ├── item_properties.csv.import
│   ├── mission_properties.csv
│   ├── mission_properties.csv.import
│   ├── player_exp_for_level.csv
│   ├── player_exp_for_level.csv.import
│   ├── recipe_properties.csv
│   ├── recipe_properties.csv.import
│   ├── tower_properties.csv
│   ├── tower_properties.csv.import
│   ├── wave_special_properties.csv
│   ├── wave_special_properties.csv.import
│   ├── wisdom_upgrades.csv
│   └── wisdom_upgrades.csv.import
├── export_presets.cfg
├── project.godot
├── rclone-filter
├── resources/
│   ├── README.md
│   ├── button_groups/
│   │   ├── element_filter_button_group.tres
│   │   ├── interface_size_setting_button_group.tres
│   │   ├── item_type_filter_button_group.tres
│   │   ├── menu_cards_button_group.tres
│   │   ├── right_panel_button_group.tres
│   │   └── speed_button_group.tres
│   ├── icons/
│   │   ├── amulets/
│   │   │   ├── amulet_01.tres
│   │   │   ├── amulet_02.tres
│   │   │   ├── amulet_03.tres
│   │   │   └── amulet_04.tres
│   │   ├── animals/
│   │   │   ├── bat_01.tres
│   │   │   ├── bat_02.tres
│   │   │   ├── bat_03.tres
│   │   │   ├── cow.tres
│   │   │   ├── dragon_01.tres
│   │   │   ├── dragon_02.tres
│   │   │   ├── dragon_03.tres
│   │   │   ├── dragon_04.tres
│   │   │   ├── dragon_05.tres
│   │   │   ├── fish_01.tres
│   │   │   ├── fish_02.tres
│   │   │   ├── fish_03.tres
│   │   │   ├── fish_04.tres
│   │   │   ├── mech_toad.tres
│   │   │   ├── piglet_warrior.tres
│   │   │   ├── rabbit.tres
│   │   │   ├── rooster_warrior.tres
│   │   │   ├── spider_01.tres
│   │   │   ├── spider_02.tres
│   │   │   ├── spider_03.tres
│   │   │   └── wing.tres
│   │   ├── armor/
│   │   │   ├── chest_plate.tres
│   │   │   ├── chest_plate_with_spike.tres
│   │   │   ├── coat.tres
│   │   │   ├── lightning_boot.tres
│   │   │   ├── vest_01.tres
│   │   │   ├── vest_02.tres
│   │   │   ├── vest_03.tres
│   │   │   └── vest_04.tres
│   │   ├── blunt_weapons/
│   │   │   ├── hammer_01.tres
│   │   │   ├── hammer_02.tres
│   │   │   ├── hammer_03.tres
│   │   │   ├── hammer_04.tres
│   │   │   ├── wood_01.tres
│   │   │   ├── wood_02.tres
│   │   │   ├── wood_03.tres
│   │   │   └── wood_04.tres
│   │   ├── books/
│   │   │   ├── book_01.tres
│   │   │   ├── book_02.tres
│   │   │   ├── book_03.tres
│   │   │   ├── book_04.tres
│   │   │   ├── book_05.tres
│   │   │   ├── book_06.tres
│   │   │   ├── book_07.tres
│   │   │   ├── book_08.tres
│   │   │   ├── book_09.tres
│   │   │   ├── book_10.tres
│   │   │   ├── book_11.tres
│   │   │   ├── note_01.tres
│   │   │   ├── note_02.tres
│   │   │   ├── note_03.tres
│   │   │   └── note_04.tres
│   │   ├── bows/
│   │   │   ├── arrow_01.tres
│   │   │   ├── arrow_02.tres
│   │   │   ├── bow_01.tres
│   │   │   ├── bow_02.tres
│   │   │   ├── bow_03.tres
│   │   │   ├── bow_04.tres
│   │   │   ├── bow_05.tres
│   │   │   └── bow_06.tres
│   │   ├── cannons/
│   │   │   ├── cannon_01.tres
│   │   │   ├── cannon_02.tres
│   │   │   ├── cannon_03.tres
│   │   │   ├── cannon_04.tres
│   │   │   ├── cannon_05.tres
│   │   │   ├── cannon_06.tres
│   │   │   ├── cannon_07.tres
│   │   │   ├── cannon_08.tres
│   │   │   ├── gun_01.tres
│   │   │   └── gun_02.tres
│   │   ├── clubs/
│   │   │   ├── club_01.tres
│   │   │   ├── club_02.tres
│   │   │   ├── club_03.tres
│   │   │   ├── club_04.tres
│   │   │   ├── club_04_without_handle.tres
│   │   │   └── club_glowing.tres
│   │   ├── creep_icons/
│   │   │   ├── challenge_challenge_boss.tres
│   │   │   ├── challenge_challenge_mass.tres
│   │   │   ├── humanoid_air.tres
│   │   │   ├── humanoid_boss.tres
│   │   │   ├── humanoid_champion.tres
│   │   │   ├── humanoid_mass.tres
│   │   │   ├── humanoid_normal.tres
│   │   │   ├── magic_air.tres
│   │   │   ├── magic_boss.tres
│   │   │   ├── magic_champion.tres
│   │   │   ├── magic_mass.tres
│   │   │   ├── magic_normal.tres
│   │   │   ├── nature_air.tres
│   │   │   ├── nature_boss.tres
│   │   │   ├── nature_champion.tres
│   │   │   ├── nature_mass.tres
│   │   │   ├── nature_normal.tres
│   │   │   ├── orc_air.tres
│   │   │   ├── orc_boss.tres
│   │   │   ├── orc_champion.tres
│   │   │   ├── orc_mass.tres
│   │   │   ├── orc_normal.tres
│   │   │   ├── undead_air.tres
│   │   │   ├── undead_boss.tres
│   │   │   ├── undead_champion.tres
│   │   │   ├── undead_mass.tres
│   │   │   └── undead_normal.tres
│   │   ├── daggers/
│   │   │   ├── dagger_01.tres
│   │   │   ├── dagger_02.tres
│   │   │   ├── dagger_03.tres
│   │   │   ├── dagger_04.tres
│   │   │   ├── dagger_05.tres
│   │   │   ├── dagger_06.tres
│   │   │   ├── dagger_07.tres
│   │   │   ├── dagger_08.tres
│   │   │   └── dagger_09.tres
│   │   ├── dioramas/
│   │   │   ├── book_display.tres
│   │   │   ├── church.tres
│   │   │   ├── fountain.tres
│   │   │   ├── mountain.tres
│   │   │   └── pyramid.tres
│   │   ├── electricity/
│   │   │   ├── electricity_blue.tres
│   │   │   ├── electricity_yellow.tres
│   │   │   ├── lightning_circle_cyan.tres
│   │   │   ├── lightning_circle_white.tres
│   │   │   ├── lightning_glowing.tres
│   │   │   └── thunderstorm.tres
│   │   ├── elements/
│   │   │   ├── astral.tres
│   │   │   ├── darkness.tres
│   │   │   ├── fire.tres
│   │   │   ├── ice.tres
│   │   │   ├── iron.tres
│   │   │   ├── nature.tres
│   │   │   └── storm.tres
│   │   ├── faces/
│   │   │   ├── green_demon.tres
│   │   │   ├── man_01.tres
│   │   │   ├── man_02.tres
│   │   │   ├── man_03.tres
│   │   │   ├── man_04.tres
│   │   │   ├── man_05.tres
│   │   │   ├── mech_zombie.tres
│   │   │   ├── orc_01.tres
│   │   │   ├── orc_02.tres
│   │   │   ├── sleeping_leaf_spirit.tres
│   │   │   ├── woman_01.tres
│   │   │   ├── woman_02.tres
│   │   │   └── woman_03.tres
│   │   ├── fire/
│   │   │   ├── burning_cloth.tres
│   │   │   ├── fire_bowl_01.tres
│   │   │   ├── fire_bowl_02.tres
│   │   │   ├── fire_bowl_03.tres
│   │   │   ├── fire_in_cup.tres
│   │   │   ├── flame_blue.tres
│   │   │   ├── flame_blue_glowing.tres
│   │   │   ├── flame_purple.tres
│   │   │   └── torch.tres
│   │   ├── food/
│   │   │   ├── barrel.tres
│   │   │   ├── beer_01.tres
│   │   │   ├── beer_02.tres
│   │   │   ├── lard.tres
│   │   │   ├── pork.tres
│   │   │   ├── pork_without_plate.tres
│   │   │   └── poultry.tres
│   │   ├── furniture/
│   │   │   ├── artifact_of_skadi.tres
│   │   │   ├── artifact_on_pedestal.tres
│   │   │   ├── bed.tres
│   │   │   ├── chest.tres
│   │   │   ├── exploding_mirror.tres
│   │   │   ├── furniture.tres
│   │   │   ├── stool.tres
│   │   │   ├── throne.tres
│   │   │   └── wooden_stand_with_nail.tres
│   │   ├── gems/
│   │   │   ├── crystal.tres
│   │   │   ├── earring_01.tres
│   │   │   ├── earring_02.tres
│   │   │   ├── earring_03.tres
│   │   │   ├── earring_04.tres
│   │   │   ├── earring_05.tres
│   │   │   ├── gem_01.tres
│   │   │   ├── gem_02.tres
│   │   │   ├── gem_03.tres
│   │   │   ├── gem_04.tres
│   │   │   ├── gem_05.tres
│   │   │   ├── gem_06.tres
│   │   │   ├── gem_07.tres
│   │   │   ├── stone_01.tres
│   │   │   ├── stone_02.tres
│   │   │   ├── stone_03.tres
│   │   │   └── stone_04.tres
│   │   ├── generic_icons/
│   │   │   ├── README.md
│   │   │   ├── abdominal_armor.tres
│   │   │   ├── alien_skull.tres
│   │   │   ├── alligator_clip.tres
│   │   │   ├── amber_mosquito.tres
│   │   │   ├── angel_outfit.tres
│   │   │   ├── angel_wings.tres
│   │   │   ├── animal_skull.tres
│   │   │   ├── ankh.tres
│   │   │   ├── aquarius.tres
│   │   │   ├── aries.tres
│   │   │   ├── armor_vest.tres
│   │   │   ├── atomic_slashes.tres
│   │   │   ├── azul_flake.tres
│   │   │   ├── barbute.tres
│   │   │   ├── barefoot.tres
│   │   │   ├── bat_mask.tres
│   │   │   ├── beard.tres
│   │   │   ├── biceps.tres
│   │   │   ├── burning_dot.tres
│   │   │   ├── burning_meteor.tres
│   │   │   ├── charm.tres
│   │   │   ├── chest_armor.tres
│   │   │   ├── cog.tres
│   │   │   ├── egg.tres
│   │   │   ├── electric.tres
│   │   │   ├── energy_breath.tres
│   │   │   ├── fire_dash.tres
│   │   │   ├── flame.tres
│   │   │   ├── foot_trip.tres
│   │   │   ├── ghost.tres
│   │   │   ├── gold_bar.tres
│   │   │   ├── hammer_drop.tres
│   │   │   ├── holy_grail.tres
│   │   │   ├── horned_helm.tres
│   │   │   ├── hourglass.tres
│   │   │   ├── knocked_out_stars.tres
│   │   │   ├── liberty_wing.tres
│   │   │   ├── meat.tres
│   │   │   ├── mighty_force.tres
│   │   │   ├── mine_explosion.tres
│   │   │   ├── moebius_trefoil.tres
│   │   │   ├── omega.tres
│   │   │   ├── open_wound.tres
│   │   │   ├── ophiucus.tres
│   │   │   ├── orc_head.tres
│   │   │   ├── over_infinity.tres
│   │   │   ├── perpendicular_rings.tres
│   │   │   ├── pisces.tres
│   │   │   ├── poison_gas.tres
│   │   │   ├── pokecog.tres
│   │   │   ├── polar_star.tres
│   │   │   ├── rolling_energy.tres
│   │   │   ├── root_tip.tres
│   │   │   ├── round_potion.tres
│   │   │   ├── rss.tres
│   │   │   ├── semi_closed_eye.tres
│   │   │   ├── shiny_omega.tres
│   │   │   ├── spell_book.tres
│   │   │   ├── spider_web.tres
│   │   │   ├── sprint.tres
│   │   │   ├── star_swirl.tres
│   │   │   ├── triple_scratches.tres
│   │   │   ├── turtle_shell.tres
│   │   │   └── wolf_howl.tres
│   │   ├── gloves/
│   │   │   ├── curse.tres
│   │   │   ├── gloves_01.tres
│   │   │   ├── gloves_02.tres
│   │   │   ├── gloves_03.tres
│   │   │   ├── gloves_04.tres
│   │   │   ├── gloves_05.tres
│   │   │   ├── gloves_06.tres
│   │   │   ├── gloves_07.tres
│   │   │   ├── gloves_08.tres
│   │   │   ├── heal.tres
│   │   │   └── steal.tres
│   │   ├── helmets/
│   │   │   ├── crown_01.tres
│   │   │   ├── crown_02.tres
│   │   │   ├── crown_03.tres
│   │   │   ├── helmet_01.tres
│   │   │   ├── helmet_02.tres
│   │   │   ├── helmet_03.tres
│   │   │   ├── helmet_04.tres
│   │   │   ├── helmet_05.tres
│   │   │   ├── helmet_06.tres
│   │   │   ├── helmet_07.tres
│   │   │   ├── helmet_08.tres
│   │   │   ├── wizard_hat_01.tres
│   │   │   └── wizard_hat_02.tres
│   │   ├── holy/
│   │   │   ├── altar.tres
│   │   │   ├── axe.tres
│   │   │   ├── cross_01.tres
│   │   │   ├── cross_02.tres
│   │   │   ├── cross_03.tres
│   │   │   ├── orb.tres
│   │   │   ├── tombstone.tres
│   │   │   └── white_trinket.tres
│   │   ├── hud/
│   │   │   ├── dice.tres
│   │   │   ├── gem_all_rarities.tres
│   │   │   ├── gem_common.tres
│   │   │   ├── gem_rare.tres
│   │   │   ├── gem_uncommon.tres
│   │   │   ├── gem_unique.tres
│   │   │   ├── gold.tres
│   │   │   ├── item_stash.tres
│   │   │   ├── knowledge_tome.tres
│   │   │   ├── oils.tres
│   │   │   ├── recipe_distill.tres
│   │   │   ├── recipe_perfect.tres
│   │   │   ├── recipe_reassemble.tres
│   │   │   ├── recipe_rebrew.tres
│   │   │   ├── research_elements.tres
│   │   │   ├── tower_food.tres
│   │   │   └── tower_stash.tres
│   │   ├── magic/
│   │   │   ├── bowl_01.tres
│   │   │   ├── bowl_02.tres
│   │   │   ├── claw_01.tres
│   │   │   ├── claw_02.tres
│   │   │   ├── claw_03.tres
│   │   │   ├── claw_04.tres
│   │   │   ├── eye.tres
│   │   │   ├── eye_blue.tres
│   │   │   ├── eyes_many.tres
│   │   │   ├── fire.tres
│   │   │   ├── lantern.tres
│   │   │   ├── lock_01.tres
│   │   │   ├── lock_02.tres
│   │   │   ├── lock_03.tres
│   │   │   ├── lock_04.tres
│   │   │   ├── magic_stone.tres
│   │   │   └── magic_stone_green.tres
│   │   ├── masks/
│   │   │   ├── mask_01.tres
│   │   │   ├── mask_02.tres
│   │   │   ├── mask_03.tres
│   │   │   ├── mask_04.tres
│   │   │   ├── mask_05.tres
│   │   │   ├── mask_06.tres
│   │   │   └── mask_07.tres
│   │   ├── mechanical/
│   │   │   ├── alchemy_kit_01.tres
│   │   │   ├── alchemy_kit_02.tres
│   │   │   ├── alchemy_kit_03.tres
│   │   │   ├── battery.tres
│   │   │   ├── black_gold_calculator.tres
│   │   │   ├── circuit_board.tres
│   │   │   ├── compass.tres
│   │   │   ├── factory_fumes.tres
│   │   │   ├── factory_gears.tres
│   │   │   ├── gold_machine.tres
│   │   │   ├── lamp.tres
│   │   │   ├── mech_badge.tres
│   │   │   └── mech_umbrella.tres
│   │   ├── misc/
│   │   │   ├── balls_01.tres
│   │   │   ├── balls_02.tres
│   │   │   ├── balls_03.tres
│   │   │   ├── cauldron.tres
│   │   │   ├── flag_01.tres
│   │   │   ├── flag_02.tres
│   │   │   ├── flag_03.tres
│   │   │   ├── gold_cart.tres
│   │   │   ├── grenade.tres
│   │   │   ├── poison_01.tres
│   │   │   ├── poison_02.tres
│   │   │   ├── quiver.tres
│   │   │   ├── red_knight.tres
│   │   │   ├── spiky_totem_01.tres
│   │   │   ├── spiky_totem_02.tres
│   │   │   ├── teapot_01.tres
│   │   │   ├── teapot_02.tres
│   │   │   ├── teapot_03.tres
│   │   │   ├── teapot_04.tres
│   │   │   ├── toolbox_01.tres
│   │   │   └── toolbox_02.tres
│   │   ├── orbs/
│   │   │   ├── moon.tres
│   │   │   ├── orb_fire.tres
│   │   │   ├── orb_green.tres
│   │   │   ├── orb_ice.tres
│   │   │   ├── orb_ice_melting.tres
│   │   │   ├── orb_molten.tres
│   │   │   ├── orb_molten_dull.tres
│   │   │   ├── orb_shadow.tres
│   │   │   └── orb_small.tres
│   │   ├── plants/
│   │   │   ├── branch_01.tres
│   │   │   ├── branch_02.tres
│   │   │   ├── flower_01.tres
│   │   │   ├── flower_02.tres
│   │   │   ├── flower_03.tres
│   │   │   ├── flower_04.tres
│   │   │   ├── flower_05.tres
│   │   │   ├── flower_06.tres
│   │   │   ├── leaf_01.tres
│   │   │   ├── leaf_02.tres
│   │   │   ├── leaf_03.tres
│   │   │   ├── plant_in_pot.tres
│   │   │   ├── stump.tres
│   │   │   └── tree.tres
│   │   ├── potions/
│   │   │   ├── beaker_01.tres
│   │   │   ├── beaker_02.tres
│   │   │   ├── beaker_03.tres
│   │   │   ├── potion_01.tres
│   │   │   ├── potion_02.tres
│   │   │   ├── potion_03.tres
│   │   │   ├── potion_04.tres
│   │   │   ├── potion_05.tres
│   │   │   ├── potion_06.tres
│   │   │   ├── potion_07.tres
│   │   │   ├── potion_08.tres
│   │   │   ├── potion_09.tres
│   │   │   ├── potion_10.tres
│   │   │   ├── potion_blue_01.tres
│   │   │   ├── potion_blue_02.tres
│   │   │   ├── potion_blue_03.tres
│   │   │   ├── potion_blue_04.tres
│   │   │   ├── potion_blue_05.tres
│   │   │   ├── potion_cyan_01.tres
│   │   │   ├── potion_cyan_02.tres
│   │   │   ├── potion_cyan_03.tres
│   │   │   ├── potion_green_01.tres
│   │   │   ├── potion_green_02.tres
│   │   │   ├── potion_green_03.tres
│   │   │   ├── potion_heart_01.tres
│   │   │   ├── potion_heart_02.tres
│   │   │   ├── potion_orange_01.tres
│   │   │   ├── potion_orange_02.tres
│   │   │   ├── potion_orange_03.tres
│   │   │   ├── potion_purple_01.tres
│   │   │   ├── potion_purple_02.tres
│   │   │   ├── potion_purple_03.tres
│   │   │   ├── potion_red_01.tres
│   │   │   ├── potion_red_02.tres
│   │   │   ├── potion_red_03.tres
│   │   │   ├── potion_yellow_01.tres
│   │   │   └── potion_yellow_02.tres
│   │   ├── rings/
│   │   │   ├── ring_01.tres
│   │   │   ├── ring_02.tres
│   │   │   ├── ring_03.tres
│   │   │   ├── ring_04.tres
│   │   │   ├── ring_05.tres
│   │   │   ├── ring_06.tres
│   │   │   ├── ring_07.tres
│   │   │   └── ring_08.tres
│   │   ├── rockets/
│   │   │   ├── rocket_01.tres
│   │   │   ├── rocket_02.tres
│   │   │   ├── rocket_03.tres
│   │   │   ├── rocket_04.tres
│   │   │   ├── rocket_05.tres
│   │   │   ├── rocket_06.tres
│   │   │   └── rocket_07.tres
│   │   ├── scrolls/
│   │   │   ├── scroll_01.tres
│   │   │   ├── scroll_02.tres
│   │   │   ├── scroll_03.tres
│   │   │   ├── scroll_04.tres
│   │   │   ├── scroll_05.tres
│   │   │   ├── scroll_06.tres
│   │   │   ├── scroll_07.tres
│   │   │   └── scroll_08.tres
│   │   ├── shields/
│   │   │   ├── shield_bronze.tres
│   │   │   ├── shield_castle.tres
│   │   │   ├── shield_gray_with_gold_emblem.tres
│   │   │   ├── shield_green.tres
│   │   │   ├── shield_skull.tres
│   │   │   ├── shield_white.tres
│   │   │   ├── shield_with_emblem.tres
│   │   │   ├── shield_with_gold_helmet.tres
│   │   │   ├── shield_wood.tres
│   │   │   ├── shield_wood_small.tres
│   │   │   └── shield_wood_small_glowing.tres
│   │   ├── spears/
│   │   │   ├── many_spears_01.tres
│   │   │   ├── many_spears_02.tres
│   │   │   ├── spear_01.tres
│   │   │   ├── spear_02.tres
│   │   │   └── spear_03.tres
│   │   ├── statues/
│   │   │   ├── statue_01.tres
│   │   │   ├── statue_02.tres
│   │   │   ├── statue_03.tres
│   │   │   ├── statue_dwarf_01.tres
│   │   │   ├── statue_dwarf_02.tres
│   │   │   └── statue_warrior.tres
│   │   ├── staves/
│   │   │   ├── staff_01.tres
│   │   │   ├── staff_02.tres
│   │   │   ├── staff_03.tres
│   │   │   ├── staff_04.tres
│   │   │   ├── staff_05.tres
│   │   │   ├── staff_06.tres
│   │   │   ├── staff_07.tres
│   │   │   ├── wand_01.tres
│   │   │   ├── wand_02.tres
│   │   │   ├── wand_03.tres
│   │   │   ├── wand_04.tres
│   │   │   ├── wand_05.tres
│   │   │   └── wand_glowing.tres
│   │   ├── swords/
│   │   │   ├── greatsword_01.tres
│   │   │   ├── greatsword_02.tres
│   │   │   ├── greatsword_03.tres
│   │   │   ├── greatsword_04.tres
│   │   │   ├── greatsword_05.tres
│   │   │   ├── sword_01.tres
│   │   │   ├── sword_02.tres
│   │   │   ├── sword_03.tres
│   │   │   ├── sword_swing_01.tres
│   │   │   └── sword_swing_02.tres
│   │   ├── tier_icons/
│   │   │   ├── common_1.tres
│   │   │   ├── common_2.tres
│   │   │   ├── common_3.tres
│   │   │   ├── common_4.tres
│   │   │   ├── common_5.tres
│   │   │   ├── common_6.tres
│   │   │   ├── common_7.tres
│   │   │   ├── rare_1.tres
│   │   │   ├── rare_2.tres
│   │   │   ├── rare_3.tres
│   │   │   ├── rare_4.tres
│   │   │   ├── rare_5.tres
│   │   │   ├── rare_6.tres
│   │   │   ├── rare_7.tres
│   │   │   ├── uncommon_1.tres
│   │   │   ├── uncommon_2.tres
│   │   │   ├── uncommon_3.tres
│   │   │   ├── uncommon_4.tres
│   │   │   ├── uncommon_5.tres
│   │   │   ├── uncommon_6.tres
│   │   │   ├── uncommon_7.tres
│   │   │   ├── unique_1.tres
│   │   │   ├── unique_2.tres
│   │   │   ├── unique_3.tres
│   │   │   ├── unique_4.tres
│   │   │   ├── unique_5.tres
│   │   │   ├── unique_6.tres
│   │   │   └── unique_7.tres
│   │   ├── tower_icons/
│   │   │   ├── abandoned_pit.tres
│   │   │   ├── abominable_snowman.tres
│   │   │   ├── afflicted_obelisk.tres
│   │   │   ├── ancient_energy_converter.tres
│   │   │   ├── annoyed_tree.tres
│   │   │   ├── arcane_storm.tres
│   │   │   ├── area_roaster.tres
│   │   │   ├── ash_geyser.tres
│   │   │   ├── astral_lantern.tres
│   │   │   ├── astral_rift.tres
│   │   │   ├── baby_plant.tres
│   │   │   ├── baby_tuskin.tres
│   │   │   ├── ball_lightning_accelerator.tres
│   │   │   ├── basic_knowledge.tres
│   │   │   ├── black_dragon_roost.tres
│   │   │   ├── black_rock_totem.tres
│   │   │   ├── bomb_turret.tres
│   │   │   ├── bone_shrine.tres
│   │   │   ├── bonk_the_living_mountain.tres
│   │   │   ├── broken_cage.tres
│   │   │   ├── broken_circle_of_wind.tres
│   │   │   ├── broken_fire_pit.tres
│   │   │   ├── broken_lightning_rod.tres
│   │   │   ├── bronze_dragon_roost.tres
│   │   │   ├── buried_soul.tres
│   │   │   ├── burning_watchtower.tres
│   │   │   ├── burrow.tres
│   │   │   ├── caged_fire.tres
│   │   │   ├── cenarion.tres
│   │   │   ├── chaining_storm.tres
│   │   │   ├── chaos_warlock.tres
│   │   │   ├── charged_obelisk.tres
│   │   │   ├── chilled_spire.tres
│   │   │   ├── cloud_warrior.tres
│   │   │   ├── cloudy_temple_of_absorption.tres
│   │   │   ├── coconut_sapling.tres
│   │   │   ├── coin_machine.tres
│   │   │   ├── cold_obelisk.tres
│   │   │   ├── cold_troll.tres
│   │   │   ├── contraption.tres
│   │   │   ├── crimson_wyrm.tres
│   │   │   ├── cruel_fire.tres
│   │   │   ├── cursed_grounds.tres
│   │   │   ├── cute_small_spider.tres
│   │   │   ├── dark_battery.tres
│   │   │   ├── dark_fire_pit.tres
│   │   │   ├── death_knight.tres
│   │   │   ├── dimensional_flux_collector.tres
│   │   │   ├── dragon_sorcerer.tres
│   │   │   ├── drake_whisperer.tres
│   │   │   ├── dreadlord.tres
│   │   │   ├── dutchmans_grave.tres
│   │   │   ├── dwarven_forgery.tres
│   │   │   ├── ebonfrost_crystal.tres
│   │   │   ├── embershell_turtle_hatchling.tres
│   │   │   ├── energy_junction.tres
│   │   │   ├── essence_of_fury.tres
│   │   │   ├── felweed.tres
│   │   │   ├── fenced_flames.tres
│   │   │   ├── fiery_dog.tres
│   │   │   ├── fiery_pebble.tres
│   │   │   ├── fire_battery.tres
│   │   │   ├── fire_star.tres
│   │   │   ├── firestorm_cell.tres
│   │   │   ├── fisherman.tres
│   │   │   ├── forest_archer.tres
│   │   │   ├── forest_protectress.tres
│   │   │   ├── forest_troll.tres
│   │   │   ├── frost_root.tres
│   │   │   ├── frosty_rock.tres
│   │   │   ├── frozen_well.tres
│   │   │   ├── garden_of_eden.tres
│   │   │   ├── gatling_gun.tres
│   │   │   ├── genis_sage.tres
│   │   │   ├── geothermal_extractor.tres
│   │   │   ├── glaive_master.tres
│   │   │   ├── glowing_solar_orb.tres
│   │   │   ├── gnoll_thunder_mage.tres
│   │   │   ├── goblin_stronghold.tres
│   │   │   ├── grab-o-bot.tres
│   │   │   ├── green_dragon_roost.tres
│   │   │   ├── green_lightning.tres
│   │   │   ├── greyfang.tres
│   │   │   ├── gryphon_rider.tres
│   │   │   ├── hall_of_souls.tres
│   │   │   ├── harby.tres
│   │   │   ├── harpy_witch.tres
│   │   │   ├── haunted_rubble.tres
│   │   │   ├── healing_obelisk.tres
│   │   │   ├── helicopter_zone.tres
│   │   │   ├── hell_bat.tres
│   │   │   ├── holy_energy.tres
│   │   │   ├── ice_battery.tres
│   │   │   ├── icy_core.tres
│   │   │   ├── icy_skulls.tres
│   │   │   ├── icy_spirit.tres
│   │   │   ├── igloo.tres
│   │   │   ├── inexperienced_huntress.tres
│   │   │   ├── inflamed_stone.tres
│   │   │   ├── initiate_elementalist.tres
│   │   │   ├── it.tres
│   │   │   ├── jungle_stalker.tres
│   │   │   ├── kraken.tres
│   │   │   ├── lesser_astral_defender.tres
│   │   │   ├── lesser_dark_defender.tres
│   │   │   ├── lesser_elemental_ghost.tres
│   │   │   ├── lesser_flamy_defender.tres
│   │   │   ├── lesser_ice_defender.tres
│   │   │   ├── lesser_iron_defender.tres
│   │   │   ├── lesser_natural_defender.tres
│   │   │   ├── lesser_priest.tres
│   │   │   ├── lesser_skeletal_mage.tres
│   │   │   ├── lesser_storm_defender.tres
│   │   │   ├── lesser_wolves_den.tres
│   │   │   ├── library_of_alexandria.tres
│   │   │   ├── lich_king.tres
│   │   │   ├── lightning_eye.tres
│   │   │   ├── lightning_generator.tres
│   │   │   ├── lightning_totem.tres
│   │   │   ├── little_phoenix.tres
│   │   │   ├── living_volcano.tres
│   │   │   ├── lunar_emitter.tres
│   │   │   ├── lunar_sentinel.tres
│   │   │   ├── magic_battery.tres
│   │   │   ├── magic_mushroom.tres
│   │   │   ├── magna_warrior.tres
│   │   │   ├── mana-touched_drake.tres
│   │   │   ├── marine.tres
│   │   │   ├── meteor_totem.tres
│   │   │   ├── militia_watchtower.tres
│   │   │   ├── miner.tres
│   │   │   ├── minor_magic_ruin.tres
│   │   │   ├── mister_fireflies.tres
│   │   │   ├── monolith_of_chaos.tres
│   │   │   ├── morphling.tres
│   │   │   ├── mossy_acid_sprayer.tres
│   │   │   ├── mud_golem.tres
│   │   │   ├── nature_sprites.tres
│   │   │   ├── necromantic_altar.tres
│   │   │   ├── nortrom_the_silencer.tres
│   │   │   ├── nuclear_missile_launcher.tres
│   │   │   ├── obelisk_of_fortuity.tres
│   │   │   ├── owl_of_wisdom.tres
│   │   │   ├── particle_accelerator.tres
│   │   │   ├── phantom.tres
│   │   │   ├── plagued_crypt.tres
│   │   │   ├── planar_gate.tres
│   │   │   ├── poison_battery.tres
│   │   │   ├── polar_bear_cub.tres
│   │   │   ├── portal_to_swine_purgatory.tres
│   │   │   ├── prince_of_lightning.tres
│   │   │   ├── princess_of_light.tres
│   │   │   ├── razorboar_thornweaver.tres
│   │   │   ├── red_ball_lightning.tres
│   │   │   ├── regenerating_well.tres
│   │   │   ├── rooted_chasm.tres
│   │   │   ├── rotted_flashing_grave.tres
│   │   │   ├── rowing_boat.tres
│   │   │   ├── ruined_monolith.tres
│   │   │   ├── ruined_storm_cap.tres
│   │   │   ├── ruined_sun_pedestal.tres
│   │   │   ├── ruined_wind_tower.tres
│   │   │   ├── rundown_iron_sentry.tres
│   │   │   ├── sacred_altar.tres
│   │   │   ├── sacrificial_lamb.tres
│   │   │   ├── safirons_cold_grave.tres
│   │   │   ├── scales.tres
│   │   │   ├── sea_turtle.tres
│   │   │   ├── servant_of_the_twin_flames.tres
│   │   │   ├── sewer_connection.tres
│   │   │   ├── shadow.tres
│   │   │   ├── shaman.tres
│   │   │   ├── shard_of_souls.tres
│   │   │   ├── silver_knight.tres
│   │   │   ├── skink.tres
│   │   │   ├── small_brazier.tres
│   │   │   ├── small_bug_nest.tres
│   │   │   ├── small_cactus.tres
│   │   │   ├── small_fire_sprayer.tres
│   │   │   ├── small_frost_fire.tres
│   │   │   ├── small_frozen_mushroom.tres
│   │   │   ├── small_ice_mine.tres
│   │   │   ├── small_light.tres
│   │   │   ├── small_pocket_rocket.tres
│   │   │   ├── small_ray_blaster.tres
│   │   │   ├── small_serpent_ward.tres
│   │   │   ├── small_torch.tres
│   │   │   ├── sniper.tres
│   │   │   ├── snowy_pebble.tres
│   │   │   ├── solar_collector.tres
│   │   │   ├── solar_emitter.tres
│   │   │   ├── sorceress.tres
│   │   │   ├── soul_vault.tres
│   │   │   ├── soulflame_device.tres
│   │   │   ├── spell_collector.tres
│   │   │   ├── spider_queen.tres
│   │   │   ├── star_gazer.tres
│   │   │   ├── storm_battery.tres
│   │   │   ├── storm_coil.tres
│   │   │   ├── storm_focus.tres
│   │   │   ├── stormy_dog.tres
│   │   │   ├── sun_crusader.tres
│   │   │   ├── taita_the_hermit.tres
│   │   │   ├── teacher.tres
│   │   │   ├── tentacle_spawn.tres
│   │   │   ├── the_conduit.tres
│   │   │   ├── the_council_of_demons.tres
│   │   │   ├── the_fire_lord.tres
│   │   │   ├── the_frozen_wyrm.tres
│   │   │   ├── the_furnace.tres
│   │   │   ├── the_omnislasher.tres
│   │   │   ├── the_steam_engine.tres
│   │   │   ├── thief_apprentice.tres
│   │   │   ├── tidewater_stream.tres
│   │   │   ├── time_manipulator.tres
│   │   │   ├── timevault.tres
│   │   │   ├── tiny_shrub.tres
│   │   │   ├── tiny_storm_lantern.tres
│   │   │   ├── tombstone.tres
│   │   │   ├── trash_heap.tres
│   │   │   ├── tree_stump.tres
│   │   │   ├── tundra_stalker.tres
│   │   │   ├── undisturbed_crypt.tres
│   │   │   ├── valor.tres
│   │   │   ├── village_witch.tres
│   │   │   ├── void_drake.tres
│   │   │   ├── vulshok_the_berserker.tres
│   │   │   ├── warrior_of_light.tres
│   │   │   ├── wild_warbeast.tres
│   │   │   ├── witch_doctor.tres
│   │   │   ├── wooden_trap.tres
│   │   │   ├── xeno_research_facility.tres
│   │   │   ├── ymir.tres
│   │   │   ├── young_northern_troll.tres
│   │   │   ├── zealot.tres
│   │   │   └── zeus.tres
│   │   ├── tower_variations/
│   │   │   ├── ash_geyser_blue.tres
│   │   │   ├── ash_geyser_green.tres
│   │   │   ├── ash_geyser_purple.tres
│   │   │   ├── bonk_the_living_mountain_small.tres
│   │   │   ├── forest_troll_small.tres
│   │   │   ├── meteor_totem_blue.tres
│   │   │   ├── meteor_totem_purple.tres
│   │   │   ├── mossy_acid_sprayer_gray.tres
│   │   │   ├── mossy_acid_sprayer_red.tres
│   │   │   ├── undisturbed_crypt_gold.tres
│   │   │   └── vulshok_the_berserker_blue.tres
│   │   ├── trinkets/
│   │   │   ├── claw_01.tres
│   │   │   ├── claw_02.tres
│   │   │   ├── claw_03.tres
│   │   │   ├── key_01.tres
│   │   │   ├── key_02.tres
│   │   │   ├── key_03.tres
│   │   │   ├── trinket_01.tres
│   │   │   ├── trinket_02.tres
│   │   │   ├── trinket_03.tres
│   │   │   ├── trinket_04.tres
│   │   │   ├── trinket_05.tres
│   │   │   ├── trinket_06.tres
│   │   │   ├── trinket_07.tres
│   │   │   ├── trinket_08.tres
│   │   │   ├── trinket_09.tres
│   │   │   └── trinket_10.tres
│   │   ├── undead/
│   │   │   ├── demon_emblem.tres
│   │   │   ├── monster_hand.tres
│   │   │   ├── skull_01.tres
│   │   │   ├── skull_02.tres
│   │   │   ├── skull_03.tres
│   │   │   ├── skull_04.tres
│   │   │   ├── skull_05.tres
│   │   │   ├── skull_06.tres
│   │   │   ├── skull_doll.tres
│   │   │   ├── skull_phazing.tres
│   │   │   ├── skull_wand_01.tres
│   │   │   ├── skull_wand_02.tres
│   │   │   ├── skull_wand_03.tres
│   │   │   └── skull_wand_04.tres
│   │   └── weapons_misc/
│   │       ├── axe_01.tres
│   │       ├── axe_02.tres
│   │       ├── barbed_spike.tres
│   │       ├── glaive_01.tres
│   │       ├── glaive_02.tres
│   │       ├── glaive_03.tres
│   │       ├── mining_pick_01.tres
│   │       ├── mining_pick_02.tres
│   │       ├── trident_01.tres
│   │       └── trident_02.tres
│   ├── misc/
│   │   ├── barrel.tres
│   │   └── pulsing_dot.tres
│   ├── shaders/
│   │   ├── foggy_camera.gdshader
│   │   ├── glowing_outline.gdshader
│   │   ├── glowing_outline.material
│   │   ├── glowing_outline_2.gdshader
│   │   └── saturation_burn.gdshader
│   ├── theme/
│   │   ├── common/
│   │   │   ├── rect_container_center_l.tres
│   │   │   ├── rect_container_l.tres
│   │   │   ├── rect_container_m.tres
│   │   │   ├── rect_container_s.tres
│   │   │   └── tab_container_m.tres
│   │   ├── element_towers_info/
│   │   │   └── empty_button_style_box.tres
│   │   ├── health_bar_background.tres
│   │   ├── health_bar_fill.tres
│   │   ├── item_button_hover.tres
│   │   ├── item_button_normal.tres
│   │   ├── item_button_pressed.tres
│   │   ├── mission_complete_indicator.tres
│   │   ├── player_resource_display/
│   │   │   ├── circle_container_l.tres
│   │   │   ├── rect_container_center_l.tres
│   │   │   ├── rect_container_left_l.tres
│   │   │   ├── rect_container_right_l.tres
│   │   │   ├── rect_container_top_menu.tres
│   │   │   ├── resource_status_panel.tres
│   │   │   └── stash_panel_background.tres
│   │   ├── selected_unit_info/
│   │   │   ├── mana_bar_fill.tres
│   │   │   ├── panel_container.tres
│   │   │   └── progress_bar_background.tres
│   │   ├── tower_actions/
│   │   │   ├── button_disabled.tres
│   │   │   ├── button_normal.tres
│   │   │   └── button_pressed.tres
│   │   ├── unit_button/
│   │   │   ├── button_disabled.tres
│   │   │   ├── button_hover.tres
│   │   │   ├── button_normal.tres
│   │   │   ├── common_rarity_panel_container.tres
│   │   │   ├── passive_ability_button.tres
│   │   │   ├── rare_rarity_panel_container.tres
│   │   │   ├── small_button_disabled.tres
│   │   │   ├── small_button_hover.tres
│   │   │   ├── small_button_normal.tres
│   │   │   ├── uncommon_rarity_panel_container.tres
│   │   │   └── unique_rarity_panel_container.tres
│   │   ├── unit_button_container/
│   │   │   └── counter_label_normal.tres
│   │   ├── unit_menu/
│   │   │   ├── button_disalbed.tres
│   │   │   ├── button_hover.tres
│   │   │   ├── button_normal.tres
│   │   │   ├── exp_bar_background.tres
│   │   │   ├── exp_bar_fill.tres
│   │   │   ├── health_bar_background.tres
│   │   │   ├── health_bar_fill.tres
│   │   │   ├── mana_bar_background.tres
│   │   │   ├── mana_bar_fill.tres
│   │   │   ├── title_button_normal.tres
│   │   │   ├── unit_level_label_normal.tres
│   │   │   ├── unit_menu_panel.tres
│   │   │   └── unit_name_label_normal.tres
│   │   └── wc3_theme.tres
│   ├── tilesets/
│   │   ├── buildable_area_tiles.tres
│   │   └── decorations.tres
│   └── ui_textures/
│       ├── buff_group_both.tres
│       ├── buff_group_incoming.tres
│       ├── buff_group_none.tres
│       ├── buff_group_outgoing.tres
│       ├── button_container_hover.tres
│       ├── common_background.tres
│       ├── common_unit_button.tres
│       ├── common_unit_button_hover.tres
│       ├── info_icon.tres
│       ├── menu_option_round_button.tres
│       ├── menu_option_round_button_hover.tres
│       ├── portal_lives_round_bg.tres
│       ├── rare_background.tres
│       ├── rare_unit_button.tres
│       ├── rare_unit_button_hover.tres
│       ├── rect_container_center_l.tres
│       ├── rect_container_l.tres
│       ├── rect_container_left_l.tres
│       ├── rect_container_m.tres
│       ├── rect_container_right_l.tres
│       ├── rect_container_s.tres
│       ├── rect_container_s_hover.tres
│       ├── speed_fast.tres
│       ├── speed_fastest.tres
│       ├── speed_normal.tres
│       ├── stash_panel_background.tres
│       ├── uncommon_background.tres
│       ├── uncommon_unit_button.tres
│       ├── uncommon_unit_button_hover.tres
│       ├── unique_background.tres
│       ├── unique_unit_button.tres
│       ├── unique_unit_button_hover.tres
│       ├── unit_button_disabled.tres
│       └── upgrade_icon.tres
├── src/
│   ├── README.md
│   ├── actions/
│   │   ├── action.gd
│   │   ├── action_autocast.gd
│   │   ├── action_autofill.gd
│   │   ├── action_build_tower.gd
│   │   ├── action_change_buffgroup.gd
│   │   ├── action_chat.gd
│   │   ├── action_consume_item.gd
│   │   ├── action_drop_item.gd
│   │   ├── action_focus_target.gd
│   │   ├── action_idle.gd
│   │   ├── action_move_item.gd
│   │   ├── action_research_element.gd
│   │   ├── action_roll_towers.gd
│   │   ├── action_select_builder.gd
│   │   ├── action_select_unit.gd
│   │   ├── action_select_wisdom_upgrades.gd
│   │   ├── action_sell_tower.gd
│   │   ├── action_sort_item_stash.gd
│   │   ├── action_start_next_wave.gd
│   │   ├── action_swap_items.gd
│   │   ├── action_toggle_autocast.gd
│   │   ├── action_transform_tower.gd
│   │   ├── action_transmute.gd
│   │   └── action_upgrade_tower.gd
│   ├── buffs/
│   │   ├── aura.gd
│   │   ├── aura.tscn
│   │   ├── buff.gd
│   │   ├── buff_range_area.gd
│   │   ├── buff_range_area.tscn
│   │   ├── buff_type.gd
│   │   ├── instances/
│   │   │   ├── cb_silence.gd
│   │   │   └── cb_stun.gd
│   │   ├── modification.gd
│   │   ├── modifier.gd
│   │   └── target_type.gd
│   ├── builders/
│   │   ├── builder.gd
│   │   └── instances/
│   │       ├── builder_adventurer.gd
│   │       ├── builder_antagonizer.gd
│   │       ├── builder_arch_sorceress.gd
│   │       ├── builder_backpacker.gd
│   │       ├── builder_barbarian_warlord.gd
│   │       ├── builder_benevolent_witch.gd
│   │       ├── builder_blademaster.gd
│   │       ├── builder_elementalist.gd
│   │       ├── builder_farseer.gd
│   │       ├── builder_feeble_fender.gd
│   │       ├── builder_goblin_alchemist.gd
│   │       ├── builder_iron_maiden.gd
│   │       ├── builder_master_of_encyclopedic_wisdom.gd
│   │       ├── builder_maverick.gd
│   │       ├── builder_naga_time_twister.gd
│   │       ├── builder_none.gd
│   │       ├── builder_panda_monk.gd
│   │       ├── builder_queen.gd
│   │       ├── builder_realist.gd
│   │       ├── builder_royal_assassin.gd
│   │       ├── builder_spirit_warden.gd
│   │       └── builder_veteran_pilot.gd
│   ├── creeps/
│   │   ├── creep.gd
│   │   ├── creep_blood_pool.gd
│   │   ├── creep_blood_pool.tscn
│   │   ├── creep_corpse.gd
│   │   ├── creep_corpse.tscn
│   │   ├── creep_spawner.gd
│   │   ├── creep_spawner.tscn
│   │   ├── creep_sprite.gd
│   │   ├── health_bar.gd
│   │   ├── instances/
│   │   │   ├── challenge/
│   │   │   │   ├── challenge_boss_creep.tscn
│   │   │   │   └── challenge_mass_creep.tscn
│   │   │   ├── creep.tscn
│   │   │   └── orc/
│   │   │       ├── orc_air_creep.tscn
│   │   │       ├── orc_boss_creep.tscn
│   │   │       ├── orc_champion_creep.tscn
│   │   │       ├── orc_mass_creep.tscn
│   │   │       └── orc_normal_creep.tscn
│   │   ├── packed_metadata.gd
│   │   ├── special_buffs/
│   │   │   ├── creep_armored.gd
│   │   │   ├── creep_broody.gd
│   │   │   ├── creep_dart.gd
│   │   │   ├── creep_ethereal.gd
│   │   │   ├── creep_evasion.gd
│   │   │   ├── creep_evolving.gd
│   │   │   ├── creep_fireball.gd
│   │   │   ├── creep_flock.gd
│   │   │   ├── creep_ghost.gd
│   │   │   ├── creep_gravid.gd
│   │   │   ├── creep_greater_speed.gd
│   │   │   ├── creep_greater_spell_resistance.gd
│   │   │   ├── creep_heavy_armored.gd
│   │   │   ├── creep_invisible.gd
│   │   │   ├── creep_magic_immunity.gd
│   │   │   ├── creep_mana_drain_aura.gd
│   │   │   ├── creep_manashield+.gd
│   │   │   ├── creep_manashield.gd
│   │   │   ├── creep_meaty.gd
│   │   │   ├── creep_mechanical.gd
│   │   │   ├── creep_necromancer.gd
│   │   │   ├── creep_protector.gd
│   │   │   ├── creep_purge_revenge.gd
│   │   │   ├── creep_regeneration.gd
│   │   │   ├── creep_relic_raider.gd
│   │   │   ├── creep_rich.gd
│   │   │   ├── creep_second_chance.gd
│   │   │   ├── creep_semi-mechanical.gd
│   │   │   ├── creep_slow.gd
│   │   │   ├── creep_slow_aura.gd
│   │   │   ├── creep_speed.gd
│   │   │   ├── creep_spell_resistance.gd
│   │   │   ├── creep_spellbinder.gd
│   │   │   ├── creep_strong.gd
│   │   │   ├── creep_stun_revenge.gd
│   │   │   ├── creep_ultra_wisdom.gd
│   │   │   ├── creep_unlucky.gd
│   │   │   ├── creep_xtreme_armor.gd
│   │   │   ├── creep_xtreme_evasion.gd
│   │   │   ├── creep_xtreme_regeneration.gd
│   │   │   └── creep_xtreme_speed.gd
│   │   ├── special_icons/
│   │   │   ├── CreepArmoredSpecial.tscn
│   │   │   ├── CreepBroodySpecial.tscn
│   │   │   ├── CreepDartSpecial.tscn
│   │   │   ├── CreepEtherealSpecial.tscn
│   │   │   ├── CreepEvasionSpecial.tscn
│   │   │   ├── CreepEvolvingSpecial.tscn
│   │   │   ├── CreepFireballSpecial.tscn
│   │   │   ├── CreepFlockSpecial.tscn
│   │   │   ├── CreepGhostSpecial.tscn
│   │   │   ├── CreepGravidSpecial.tscn
│   │   │   ├── CreepGreaterSpeedSpecial.tscn
│   │   │   ├── CreepGreaterSpellResistanceSpecial.tscn
│   │   │   ├── CreepHeavyArmoredSpecial.tscn
│   │   │   ├── CreepInvisibleSpecial.tscn
│   │   │   ├── CreepMagicImmunitySpecial.tscn
│   │   │   ├── CreepManaDrainAuraSpecial.tscn
│   │   │   ├── CreepManaShieldPlusSpecial.tscn
│   │   │   ├── CreepManaShieldSpecial.tscn
│   │   │   ├── CreepMeatySpecial.tscn
│   │   │   ├── CreepMechanicalSpecial.tscn
│   │   │   ├── CreepNecromancerSpecial.tscn
│   │   │   ├── CreepProtectorSpecial.tscn
│   │   │   ├── CreepPurgeRevengeSpecial.tscn
│   │   │   ├── CreepRegenerationSpecial.tscn
│   │   │   ├── CreepRelicRaiderSpecial.tscn
│   │   │   ├── CreepRichSpecial.tscn
│   │   │   ├── CreepSecondChanceSpecial.tscn
│   │   │   ├── CreepSemiMechanicalSpecial.tscn
│   │   │   ├── CreepSlowAuraSpecial.tscn
│   │   │   ├── CreepSlowSpecial.tscn
│   │   │   ├── CreepSpeedSpecial.tscn
│   │   │   ├── CreepSpellResistanceSpecial.tscn
│   │   │   ├── CreepSpellbinderSpecial.tscn
│   │   │   ├── CreepStrongSpecial.tscn
│   │   │   ├── CreepStunRevengeSpecial.tscn
│   │   │   ├── CreepUltraWisdomSpecial.tscn
│   │   │   ├── CreepUnluckySpecial.tscn
│   │   │   ├── CreepXtremeArmorSpecial.tscn
│   │   │   ├── CreepXtremeEvasionSpecial.tscn
│   │   │   ├── CreepXtremeRegenerationSpecial.tscn
│   │   │   └── CreepXtremeSpeedSpecial.tscn
│   │   ├── wave.gd
│   │   ├── wave_path.gd
│   │   ├── wave_spawner.gd
│   │   └── wave_spawner.tscn
│   ├── effects/
│   │   ├── ancient_protector_missile.tscn
│   │   ├── animated_dead_target.tscn
│   │   ├── apply_potion.tscn
│   │   ├── arcane_tower_attack.tscn
│   │   ├── arcane_tower_attack_flat.tscn
│   │   ├── avatar_caster.tscn
│   │   ├── banshee_missile.tscn
│   │   ├── barrel.tscn
│   │   ├── blink_target.tscn
│   │   ├── blood_splatter.tscn
│   │   ├── build_tower.tscn
│   │   ├── charm_target.tscn
│   │   ├── chimaera_acid.tscn
│   │   ├── cloud_of_fog_cycle.tscn
│   │   ├── cloud_of_fog_small.tscn
│   │   ├── cripple_target.tscn
│   │   ├── crushing_wave.tscn
│   │   ├── crypt_fiend_eggsack.tscn
│   │   ├── cyclone_target.tscn
│   │   ├── death_and_decay.tscn
│   │   ├── death_coil.tscn
│   │   ├── death_explode.tscn
│   │   ├── devour.tscn
│   │   ├── dispel_magic_target.tscn
│   │   ├── doom_death.tscn
│   │   ├── effects_container.gd
│   │   ├── faerie_dragon_missile.tscn
│   │   ├── firelord_death_explode.tscn
│   │   ├── flame_strike_embers.tscn
│   │   ├── flower_aura.tscn
│   │   ├── frag_boom_spawn.tscn
│   │   ├── freezing_breath.tscn
│   │   ├── freezing_breath_purple.tscn
│   │   ├── frost_armor_damage.tscn
│   │   ├── frost_armor_damage_purple.tscn
│   │   ├── frost_bolt_missile.tscn
│   │   ├── glaive.tscn
│   │   ├── gold_credit.tscn
│   │   ├── healing_wave_target.tscn
│   │   ├── holy_bolt.tscn
│   │   ├── holy_bolt_green.tscn
│   │   ├── howl_caster.tscn
│   │   ├── immolation_damage.tscn
│   │   ├── impale_hit_target.tscn
│   │   ├── impale_target_dust.tscn
│   │   ├── incinerate.tscn
│   │   ├── interpolated_sprite.gd
│   │   ├── keeper_grove_missile.tscn
│   │   ├── level_up.tscn
│   │   ├── mana_burn_target.tscn
│   │   ├── mana_shield_cycle.tscn
│   │   ├── mass_teleport_caster.tscn
│   │   ├── mass_teleport_target.tscn
│   │   ├── monsoon_bolt.tscn
│   │   ├── moonwell_target.tscn
│   │   ├── mortar_missile.tscn
│   │   ├── naga_death.tscn
│   │   ├── ne_cancel_death.tscn
│   │   ├── ne_death.tscn
│   │   ├── placeholder.tscn
│   │   ├── polymorph_target.tscn
│   │   ├── projectile_explosion_astral.tscn
│   │   ├── projectile_explosion_darkness.tscn
│   │   ├── projectile_explosion_fire.tscn
│   │   ├── projectile_explosion_ice.tscn
│   │   ├── projectile_explosion_iron.tscn
│   │   ├── projectile_explosion_nature.tscn
│   │   ├── projectile_explosion_storm.tscn
│   │   ├── purge_buff_target.tscn
│   │   ├── quillspray.tscn
│   │   ├── raise_skeleton.tscn
│   │   ├── replenish_mana.tscn
│   │   ├── revive_human.tscn
│   │   ├── roar.tscn
│   │   ├── roots.tscn
│   │   ├── shackle.tscn
│   │   ├── shockwave_missile.tscn
│   │   ├── silence_area.tscn
│   │   ├── small_flame_spawn.tscn
│   │   ├── spell_aiil.tscn
│   │   ├── spell_ailb.tscn
│   │   ├── spell_aima.tscn
│   │   ├── spell_aire.tscn
│   │   ├── spell_aire_flat.tscn
│   │   ├── spell_aiso.tscn
│   │   ├── spell_alim.tscn
│   │   ├── spell_breaker_target.tscn
│   │   ├── spirit_link_target.tscn
│   │   ├── stampede_missile_death.tscn
│   │   ├── starfall_target.tscn
│   │   ├── stun_visual.tscn
│   │   ├── target_arrow.gd
│   │   ├── target_arrow.tscn
│   │   ├── thunder_clap.tscn
│   │   ├── undead_dissipate.tscn
│   │   ├── upgrade_tower.tscn
│   │   ├── vampiric_aura.tscn
│   │   ├── voodoo_aura.tscn
│   │   ├── warstomp_caster.tscn
│   │   ├── wind_shear.tscn
│   │   ├── wisp_explode.tscn
│   │   ├── witch_doctor_ward.tscn
│   │   ├── ziggurat_frost_missile.tscn
│   │   └── zombify_target.tscn
│   ├── enums/
│   │   ├── README.md
│   │   ├── armor_type.gd
│   │   ├── attack_type.gd
│   │   ├── buff_group_mode.gd
│   │   ├── builder_tier.gd
│   │   ├── creep_category.gd
│   │   ├── creep_size.gd
│   │   ├── difficulty.gd
│   │   ├── display_mode.gd
│   │   ├── element.gd
│   │   ├── game_mode.gd
│   │   ├── item_type.gd
│   │   ├── language.gd
│   │   ├── modification_type.gd
│   │   ├── player_mode.gd
│   │   ├── rarity.gd
│   │   └── team_mode.gd
│   ├── game_scene/
│   │   ├── build_space.gd
│   │   ├── build_tower.gd
│   │   ├── camera_controller.gd
│   │   ├── chat_commands.gd
│   │   ├── combat_log_storage.gd
│   │   ├── game_client.gd
│   │   ├── game_client.tscn
│   │   ├── game_host.gd
│   │   ├── game_host.tscn
│   │   ├── game_scene.gd
│   │   ├── game_scene.tscn
│   │   ├── game_time.gd
│   │   ├── horadric_cube.gd
│   │   ├── manual_timer.gd
│   │   ├── mouse_state.gd
│   │   ├── move_item.gd
│   │   ├── select_point_for_cast.gd
│   │   ├── select_target_for_cast.gd
│   │   ├── select_unit.gd
│   │   ├── team_container.gd
│   │   └── tutorial_controller.gd
│   ├── items/
│   │   ├── README.md
│   │   ├── item.gd
│   │   ├── item_behavior.gd
│   │   ├── item_behaviors/
│   │   │   ├── aqueous_vapor.gd
│   │   │   ├── arcane_book_of_power.gd
│   │   │   ├── arcane_oil_of_lore.gd
│   │   │   ├── arcane_script.gd
│   │   │   ├── arms_dealer.gd
│   │   │   ├── artifact_of_skadi.gd
│   │   │   ├── backpack.gd
│   │   │   ├── ball_lightning.gd
│   │   │   ├── bartucs_spirit.gd
│   │   │   ├── basics_of_calculus.gd
│   │   │   ├── bhaals_essence.gd
│   │   │   ├── blaster_staff.gd
│   │   │   ├── bloodthirsty_wheel_of_fortune.gd
│   │   │   ├── bloody_key.gd
│   │   │   ├── bones_of_essence.gd
│   │   │   ├── bonks_face.gd
│   │   │   ├── book_of_force.gd
│   │   │   ├── book_of_knowledge.gd
│   │   │   ├── brimstone_helmet.gd
│   │   │   ├── chameleon_glaive.gd
│   │   │   ├── chameleons_soul.gd
│   │   │   ├── charged_disk.gd
│   │   │   ├── chrono_jumper.gd
│   │   │   ├── circle_of_power.gd
│   │   │   ├── commander.gd
│   │   │   ├── consumable_chicken.gd
│   │   │   ├── consumable_hobbit.gd
│   │   │   ├── consumable_piggy.gd
│   │   │   ├── consumable_plant.gd
│   │   │   ├── crescent_stone.gd
│   │   │   ├── crit_blade.gd
│   │   │   ├── cruel_torch.gd
│   │   │   ├── currency_converter.gd
│   │   │   ├── cursed_claw.gd
│   │   │   ├── dagger_of_bane.gd
│   │   │   ├── dark_matter_trident.gd
│   │   │   ├── deep_shadows.gd
│   │   │   ├── distorted_idol.gd
│   │   │   ├── divine_book_of_omnipotence.gd
│   │   │   ├── dooms_ensign.gd
│   │   │   ├── elunes_bow.gd
│   │   │   ├── empty_item_behavior.gd
│   │   │   ├── enchanted_knives.gd
│   │   │   ├── essence_of_rot.gd
│   │   │   ├── even_more_magical_hammer.gd
│   │   │   ├── excalibur.gd
│   │   │   ├── eye_of_true_sight.gd
│   │   │   ├── faithful_staff.gd
│   │   │   ├── fist_of_doom.gd
│   │   │   ├── flag_of_the_allegiance.gd
│   │   │   ├── forcefield_generator.gd
│   │   │   ├── fragmentation_round.gd
│   │   │   ├── frog_pipe.gd
│   │   │   ├── glaive_of_supreme_follow_up.gd
│   │   │   ├── golden_decoration.gd
│   │   │   ├── golden_trident.gd
│   │   │   ├── granite_hammer.gd
│   │   │   ├── grounding_gloves.gd
│   │   │   ├── haunted_hand.gd
│   │   │   ├── helm_of_insanity.gd
│   │   │   ├── hippogryph_egg.gd
│   │   │   ├── holy_hand_grenade.gd
│   │   │   ├── item_template_advanced.gd
│   │   │   ├── jah_rakals_fury.gd
│   │   │   ├── jewels_of_the_moon.gd
│   │   │   ├── jungle_stalkers_doll.gd
│   │   │   ├── libram_of_grace.gd
│   │   │   ├── lich_mask.gd
│   │   │   ├── liquid_gold.gd
│   │   │   ├── lucky_gem.gd
│   │   │   ├── lunar_essence.gd
│   │   │   ├── magic_conductor.gd
│   │   │   ├── magic_gloves.gd
│   │   │   ├── magic_hammer.gd
│   │   │   ├── magic_link.gd
│   │   │   ├── magnetic_field.gd
│   │   │   ├── mana_stone.gd
│   │   │   ├── medallion_of_opulence.gd
│   │   │   ├── mefis_rocket.gd
│   │   │   ├── mighty_trees_acorns.gd
│   │   │   ├── mindleecher.gd
│   │   │   ├── mine_cart.gd
│   │   │   ├── mini_forest_troll.gd
│   │   │   ├── mining_tools.gd
│   │   │   ├── mystical_shell.gd
│   │   │   ├── nerminds_eye.gd
│   │   │   ├── never-ending_keg.gd
│   │   │   ├── oil_of_lore.gd
│   │   │   ├── old_hunter.gd
│   │   │   ├── optimists_preserved_face.gd
│   │   │   ├── orb_of_souls.gd
│   │   │   ├── overcharge_shot.gd
│   │   │   ├── pendant_of_mana_supremacy.gd
│   │   │   ├── pendant_of_promptness.gd
│   │   │   ├── phase_gloves.gd
│   │   │   ├── plain_staff.gd
│   │   │   ├── pocket_emporium.gd
│   │   │   ├── polarisator.gd
│   │   │   ├── portable_tombstone.gd
│   │   │   ├── priest_figurine.gd
│   │   │   ├── purifying_gloves.gd
│   │   │   ├── ritual_talisman.gd
│   │   │   ├── scroll_of_piercing_magic.gd
│   │   │   ├── scroll_of_speed.gd
│   │   │   ├── scroll_of_strength.gd
│   │   │   ├── seekers_arcane_oil.gd
│   │   │   ├── seekers_oil.gd
│   │   │   ├── share_knowledge.gd
│   │   │   ├── shining_rock.gd
│   │   │   ├── shrapnel_ammunition.gd
│   │   │   ├── sign_of_energy_infusion.gd
│   │   │   ├── silver_armor.gd
│   │   │   ├── sleeve_of_rage.gd
│   │   │   ├── soul_collectors_cloak.gd
│   │   │   ├── soul_collectors_scythe.gd
│   │   │   ├── soul_extractor.gd
│   │   │   ├── spear_of_loki.gd
│   │   │   ├── speed_demons_reward.gd
│   │   │   ├── spellbook_of_item_mastery.gd
│   │   │   ├── spider_broach.gd
│   │   │   ├── spiderling.gd
│   │   │   ├── staff_of_essence.gd
│   │   │   ├── staff_of_the_wild_equus.gd
│   │   │   ├── stasis_trap.gd
│   │   │   ├── strange_item.gd
│   │   │   ├── stunner.gd
│   │   │   ├── sword_of_decay.gd
│   │   │   ├── sword_of_reckoning.gd
│   │   │   ├── the_divine_wings_of_tragedy.gd
│   │   │   ├── toy_boy.gd
│   │   │   ├── unstable_current.gd
│   │   │   ├── unyielding_maul.gd
│   │   │   ├── vampiric_skull.gd
│   │   │   ├── wand_of_mana_zap.gd
│   │   │   ├── wanted_list.gd
│   │   │   ├── war_drum.gd
│   │   │   ├── wise_mans_cooking_recipe.gd
│   │   │   ├── wizards_soul.gd
│   │   │   ├── wooden_leg.gd
│   │   │   ├── workbench.gd
│   │   │   └── writers_knowledge.gd
│   │   ├── item_container.gd
│   │   ├── item_drop.gd
│   │   ├── item_drop.tscn
│   │   └── tower_item_container.gd
│   ├── map/
│   │   ├── buildable_area.gd
│   │   ├── buildable_area.tscn
│   │   ├── map.gd
│   │   ├── map_big.tscn
│   │   └── map_small.tscn
│   ├── missions/
│   │   ├── instances/
│   │   │   ├── mission_120_in_60min.gd
│   │   │   ├── mission_240_in_120min.gd
│   │   │   ├── mission_35_food_or_less.gd
│   │   │   ├── mission_empty.gd
│   │   │   ├── mission_no_items.gd
│   │   │   ├── mission_no_oils.gd
│   │   │   ├── mission_only_astral_towers.gd
│   │   │   ├── mission_only_common_uncommon.gd
│   │   │   ├── mission_only_darkness_towers.gd
│   │   │   ├── mission_only_fire_towers.gd
│   │   │   ├── mission_only_ice_towers.gd
│   │   │   ├── mission_only_iron_towers.gd
│   │   │   ├── mission_only_nature_towers.gd
│   │   │   └── mission_only_storm_towers.gd
│   │   ├── mission.gd
│   │   ├── mission_manager.gd
│   │   └── mission_manager.tscn
│   ├── player/
│   │   ├── auto_oil.gd
│   │   ├── camera_origin.gd
│   │   ├── camera_origin.tscn
│   │   ├── player.gd
│   │   ├── player.tscn
│   │   ├── team.gd
│   │   ├── team.tscn
│   │   └── tower_stash.gd
│   ├── projectiles/
│   │   ├── projectile.gd
│   │   ├── projectile.tscn
│   │   ├── projectile_type.gd
│   │   └── projectile_visuals/
│   │       ├── ball_lightning_projectile.tscn
│   │       ├── default_projectile.gd
│   │       ├── default_projectile.tscn
│   │       ├── energy_ball.tscn
│   │       ├── flying_pork.tscn
│   │       ├── omnislasher_mirror_image.tscn
│   │       └── quillspray_projectile.tscn
│   ├── singletons/
│   │   ├── README.md
│   │   ├── button_sounds.gd
│   │   ├── combat_log.gd
│   │   ├── config.gd
│   │   ├── constants.gd
│   │   ├── effect.gd
│   │   ├── elapsed_timer.gd
│   │   ├── event_bus.gd
│   │   ├── experience.gd
│   │   ├── experience_password.gd
│   │   ├── globals.gd
│   │   ├── group_manager.gd
│   │   ├── item_drop_calc.gd
│   │   ├── messages.gd
│   │   ├── mission_status.gd
│   │   ├── mission_tracking.gd
│   │   ├── nakama_connection.gd
│   │   ├── player_experience.gd
│   │   ├── player_manager.gd
│   │   ├── preloads.gd
│   │   ├── properties/
│   │   │   ├── README.md
│   │   │   ├── ability_properties.gd
│   │   │   ├── aura_properties.gd
│   │   │   ├── autocast_properties.gd
│   │   │   ├── builder_properties.gd
│   │   │   ├── item_properties.gd
│   │   │   ├── mission_properties.gd
│   │   │   ├── recipe_properties.gd
│   │   │   ├── tower_properties.gd
│   │   │   ├── tutorial_properties.gd
│   │   │   ├── wave_special_properties.gd
│   │   │   └── wisdom_upgrade_properties.gd
│   │   ├── rich_texts.gd
│   │   ├── sanitize_text.gd
│   │   ├── secrets.gd
│   │   ├── settings.gd
│   │   ├── sfx.gd
│   │   ├── sfx_paths.gd
│   │   ├── tower_distribution.gd
│   │   ├── tower_sprites.gd
│   │   ├── unit_icons.gd
│   │   ├── utils.gd
│   │   ├── vector_utils.gd
│   │   └── wave_special.gd
│   ├── spells/
│   │   ├── spell_blizzard.gd
│   │   ├── spell_blizzard.tscn
│   │   ├── spell_chain_lightning.gd
│   │   ├── spell_chain_lightning.tscn
│   │   ├── spell_dummy.gd
│   │   ├── spell_dummy.tscn
│   │   ├── spell_forked_lightning.gd
│   │   ├── spell_forked_lightning.tscn
│   │   ├── spell_swarm.gd
│   │   ├── spell_swarm.tscn
│   │   └── spell_type.gd
│   ├── sprites/
│   │   ├── lightning_animation.tscn
│   │   └── pulsing_dot.tscn
│   ├── tests/
│   │   ├── README.md
│   │   ├── playtest_bot.gd
│   │   ├── test_horadric_tool.gd
│   │   ├── test_item_drop_chances.gd
│   │   ├── test_items_tool.gd
│   │   ├── test_tool.gd
│   │   ├── test_tower_sprite_size.gd
│   │   └── test_towers_tool.gd
│   ├── towers/
│   │   ├── README.md
│   │   ├── autocast.gd
│   │   ├── autocast.tscn
│   │   ├── event.gd
│   │   ├── multiboard_values.gd
│   │   ├── range_data.gd
│   │   ├── range_indicator.gd
│   │   ├── range_indicator.tscn
│   │   ├── tower.gd
│   │   ├── tower.tscn
│   │   ├── tower_behavior.gd
│   │   ├── tower_behavior_template.gd
│   │   ├── tower_behaviors/
│   │   │   ├── afflicted_obelisk.gd
│   │   │   ├── ancient_energy_converter.gd
│   │   │   ├── annoyed_tree.gd
│   │   │   ├── arcane_storm.gd
│   │   │   ├── area_roaster.gd
│   │   │   ├── ash_geyser.gd
│   │   │   ├── astral_lantern.gd
│   │   │   ├── astral_rift.gd
│   │   │   ├── baby_tuskin.gd
│   │   │   ├── ball_lightning_accelerator.gd
│   │   │   ├── basic_knowledge.gd
│   │   │   ├── black_dragon_roost.gd
│   │   │   ├── black_rock_totem.gd
│   │   │   ├── bomb_turret.gd
│   │   │   ├── bone_shrine.gd
│   │   │   ├── bonk_the_living_mountain.gd
│   │   │   ├── broken_cage.gd
│   │   │   ├── broken_circle_of_wind.gd
│   │   │   ├── broken_fire_pit.gd
│   │   │   ├── broken_lightning_rod.gd
│   │   │   ├── bronze_dragon_roost.gd
│   │   │   ├── buried_soul.gd
│   │   │   ├── burning_watchtower.gd
│   │   │   ├── burrow.gd
│   │   │   ├── caged_fire.gd
│   │   │   ├── cenarion.gd
│   │   │   ├── chaining_storm.gd
│   │   │   ├── chaos_warlock.gd
│   │   │   ├── charged_obelisk.gd
│   │   │   ├── chilled_spire.gd
│   │   │   ├── cloud_warrior.gd
│   │   │   ├── cloudy_temple_of_absorption.gd
│   │   │   ├── coconut_sapling.gd
│   │   │   ├── coin_machine.gd
│   │   │   ├── cold_obelisk.gd
│   │   │   ├── cold_troll.gd
│   │   │   ├── contraption.gd
│   │   │   ├── crimson_wyrm.gd
│   │   │   ├── cruel_fire.gd
│   │   │   ├── cursed_grounds.gd
│   │   │   ├── cute_small_spider.gd
│   │   │   ├── dark_battery.gd
│   │   │   ├── death_knight.gd
│   │   │   ├── dimensional_flux_collector.gd
│   │   │   ├── dragon_sorcerer.gd
│   │   │   ├── drake_whisperer.gd
│   │   │   ├── dreadlord.gd
│   │   │   ├── dutchmans_grave.gd
│   │   │   ├── dwarven_forgery.gd
│   │   │   ├── ebonfrost_crystal.gd
│   │   │   ├── embershell_turtle_hatchling.gd
│   │   │   ├── empty_tower_behavior.gd
│   │   │   ├── energy_junction.gd
│   │   │   ├── essence_of_fury.gd
│   │   │   ├── felweed.gd
│   │   │   ├── fenced_flames.gd
│   │   │   ├── fiery_dog.gd
│   │   │   ├── fire_battery.gd
│   │   │   ├── fire_star.gd
│   │   │   ├── firestorm_cell.gd
│   │   │   ├── fisherman.gd
│   │   │   ├── forest_archer.gd
│   │   │   ├── forest_protectress.gd
│   │   │   ├── forest_troll.gd
│   │   │   ├── frost_root.gd
│   │   │   ├── frosty_rock.gd
│   │   │   ├── frozen_well.gd
│   │   │   ├── garden_of_eden.gd
│   │   │   ├── gatling_gun.gd
│   │   │   ├── genis_sage.gd
│   │   │   ├── geothermal_extractor.gd
│   │   │   ├── glaive_master.gd
│   │   │   ├── glowing_solar_orb.gd
│   │   │   ├── gnoll_thunder_mage.gd
│   │   │   ├── goblin_stronghold.gd
│   │   │   ├── grab-o-bot.gd
│   │   │   ├── green_dragon_roost.gd
│   │   │   ├── green_lightning.gd
│   │   │   ├── greyfang.gd
│   │   │   ├── gryphon_rider.gd
│   │   │   ├── hall_of_souls.gd
│   │   │   ├── harby.gd
│   │   │   ├── harpy_witch.gd
│   │   │   ├── haunted_rubble.gd
│   │   │   ├── healing_obelisk.gd
│   │   │   ├── helicopter_zone.gd
│   │   │   ├── hell_bat.gd
│   │   │   ├── holy_energy.gd
│   │   │   ├── ice_battery.gd
│   │   │   ├── icy_core.gd
│   │   │   ├── icy_skulls.gd
│   │   │   ├── icy_spirit.gd
│   │   │   ├── igloo.gd
│   │   │   ├── inexperienced_huntress.gd
│   │   │   ├── inflamed_stone.gd
│   │   │   ├── initiate_elementalist.gd
│   │   │   ├── it.gd
│   │   │   ├── jungle_stalker.gd
│   │   │   ├── kraken.gd
│   │   │   ├── lesser_elemental_ghost.gd
│   │   │   ├── lesser_priest.gd
│   │   │   ├── lesser_skeletal_mage.gd
│   │   │   ├── lesser_wolves_den.gd
│   │   │   ├── library_of_alexandria.gd
│   │   │   ├── lich_king.gd
│   │   │   ├── lightning_eye.gd
│   │   │   ├── lightning_generator.gd
│   │   │   ├── lightning_totem.gd
│   │   │   ├── little_phoenix.gd
│   │   │   ├── living_volcano.gd
│   │   │   ├── lunar_emitter.gd
│   │   │   ├── lunar_sentinel.gd
│   │   │   ├── magic_battery.gd
│   │   │   ├── magic_mushroom.gd
│   │   │   ├── magna_warrior.gd
│   │   │   ├── mana-touched_drake.gd
│   │   │   ├── marine.gd
│   │   │   ├── meteor_totem.gd
│   │   │   ├── militia_watchtower.gd
│   │   │   ├── miner.gd
│   │   │   ├── minor_magic_ruin.gd
│   │   │   ├── mister_fireflies.gd
│   │   │   ├── monolith_of_chaos.gd
│   │   │   ├── morphling.gd
│   │   │   ├── mossy_acid_sprayer.gd
│   │   │   ├── mud_golem.gd
│   │   │   ├── nature_sprites.gd
│   │   │   ├── necromantic_altar.gd
│   │   │   ├── nortrom_the_silencer.gd
│   │   │   ├── nuclear_missile_launcher.gd
│   │   │   ├── obelisk_of_fortuity.gd
│   │   │   ├── owl_of_wisdom.gd
│   │   │   ├── particle_accelerator.gd
│   │   │   ├── phantom.gd
│   │   │   ├── plagued_crypt.gd
│   │   │   ├── planar_gate.gd
│   │   │   ├── poison_battery.gd
│   │   │   ├── polar_bear_cub.gd
│   │   │   ├── portal_to_swine_purgatory.gd
│   │   │   ├── prince_of_lightning.gd
│   │   │   ├── princess_of_light.gd
│   │   │   ├── razorboar_thornweaver.gd
│   │   │   ├── red_ball_lightning.gd
│   │   │   ├── regenerating_well.gd
│   │   │   ├── rooted_chasm.gd
│   │   │   ├── rotted_flashing_grave.gd
│   │   │   ├── rowing_boat.gd
│   │   │   ├── ruined_wind_tower.gd
│   │   │   ├── rundown_iron_sentry.gd
│   │   │   ├── sacred_altar.gd
│   │   │   ├── sacrificial_lamb.gd
│   │   │   ├── safirons_cold_grave.gd
│   │   │   ├── scales.gd
│   │   │   ├── sea_turtle.gd
│   │   │   ├── servant_of_the_twin_flames.gd
│   │   │   ├── sewer_connection.gd
│   │   │   ├── shadow.gd
│   │   │   ├── shaman.gd
│   │   │   ├── shard_of_souls.gd
│   │   │   ├── silver_knight.gd
│   │   │   ├── skink.gd
│   │   │   ├── small_bug_nest.gd
│   │   │   ├── small_fire_sprayer.gd
│   │   │   ├── small_frost_fire.gd
│   │   │   ├── small_ice_mine.gd
│   │   │   ├── small_light.gd
│   │   │   ├── small_ray_blaster.gd
│   │   │   ├── small_serpent_ward.gd
│   │   │   ├── small_torch.gd
│   │   │   ├── sniper.gd
│   │   │   ├── solar_collector.gd
│   │   │   ├── solar_emitter.gd
│   │   │   ├── sorceress.gd
│   │   │   ├── soul_vault.gd
│   │   │   ├── soulflame_device.gd
│   │   │   ├── spell_collector.gd
│   │   │   ├── spider_queen.gd
│   │   │   ├── star_gazer.gd
│   │   │   ├── storm_battery.gd
│   │   │   ├── storm_coil.gd
│   │   │   ├── storm_focus.gd
│   │   │   ├── stormy_dog.gd
│   │   │   ├── sun_crusader.gd
│   │   │   ├── taita_the_hermit.gd
│   │   │   ├── teacher.gd
│   │   │   ├── tentacle_spawn.gd
│   │   │   ├── the_conduit.gd
│   │   │   ├── the_council_of_demons.gd
│   │   │   ├── the_fire_lord.gd
│   │   │   ├── the_frozen_wyrm.gd
│   │   │   ├── the_furnace.gd
│   │   │   ├── the_omnislasher.gd
│   │   │   ├── the_steam_engine.gd
│   │   │   ├── thief_apprentice.gd
│   │   │   ├── tidewater_stream.gd
│   │   │   ├── time_manipulator.gd
│   │   │   ├── timevault.gd
│   │   │   ├── tiny_storm_lantern.gd
│   │   │   ├── tombstone.gd
│   │   │   ├── tundra_stalker.gd
│   │   │   ├── undisturbed_crypt.gd
│   │   │   ├── valor.gd
│   │   │   ├── village_witch.gd
│   │   │   ├── void_drake.gd
│   │   │   ├── vulshok_the_berserker.gd
│   │   │   ├── warrior_of_light.gd
│   │   │   ├── wild_warbeast.gd
│   │   │   ├── witch_doctor.gd
│   │   │   ├── wooden_trap.gd
│   │   │   ├── xeno_research_facility.gd
│   │   │   ├── ymir.gd
│   │   │   ├── young_northern_troll.gd
│   │   │   ├── zealot.gd
│   │   │   └── zeus.gd
│   │   ├── tower_preview.gd
│   │   ├── tower_preview.tscn
│   │   └── tower_sprites/
│   │       ├── abandoned_pit_1.tscn
│   │       ├── abandoned_pit_2.tscn
│   │       ├── abandoned_pit_3.tscn
│   │       ├── abandoned_pit_4.tscn
│   │       ├── abandoned_pit_5.tscn
│   │       ├── abominable_snowman_1.tscn
│   │       ├── abominable_snowman_2.tscn
│   │       ├── abominable_snowman_3.tscn
│   │       ├── abominable_snowman_4.tscn
│   │       ├── abominable_snowman_5.tscn
│   │       ├── afflicted_obelisk_1.tscn
│   │       ├── afflicted_obelisk_2.tscn
│   │       ├── afflicted_obelisk_3.tscn
│   │       ├── afflicted_obelisk_4.tscn
│   │       ├── ancient_energy_converter_1.tscn
│   │       ├── annoyed_tree_1.tscn
│   │       ├── annoyed_tree_2.tscn
│   │       ├── annoyed_tree_3.tscn
│   │       ├── annoyed_tree_4.tscn
│   │       ├── arcane_storm_1.tscn
│   │       ├── area_roaster_1.tscn
│   │       ├── area_roaster_2.tscn
│   │       ├── area_roaster_3.tscn
│   │       ├── ash_geyser_1.tscn
│   │       ├── ash_geyser_2.tscn
│   │       ├── ash_geyser_3.tscn
│   │       ├── ash_geyser_4.tscn
│   │       ├── ash_geyser_5.tscn
│   │       ├── astral_lantern_1.tscn
│   │       ├── astral_lantern_2.tscn
│   │       ├── astral_lantern_3.tscn
│   │       ├── astral_lantern_4.tscn
│   │       ├── astral_rift_1.tscn
│   │       ├── baby_plant_1.tscn
│   │       ├── baby_plant_2.tscn
│   │       ├── baby_plant_3.tscn
│   │       ├── baby_plant_4.tscn
│   │       ├── baby_plant_5.tscn
│   │       ├── baby_plant_6.tscn
│   │       ├── baby_tuskin_1.tscn
│   │       ├── baby_tuskin_2.tscn
│   │       ├── baby_tuskin_3.tscn
│   │       ├── ball_lightning_accelerator_1.tscn
│   │       ├── ball_lightning_accelerator_2.tscn
│   │       ├── basic_knowledge_1.tscn
│   │       ├── basic_knowledge_2.tscn
│   │       ├── basic_knowledge_3.tscn
│   │       ├── basic_knowledge_4.tscn
│   │       ├── basic_knowledge_5.tscn
│   │       ├── black_dragon_roost_1.tscn
│   │       ├── black_rock_totem_1.tscn
│   │       ├── bomb_turret_1.tscn
│   │       ├── bomb_turret_2.tscn
│   │       ├── bone_shrine_1.tscn
│   │       ├── bone_shrine_2.tscn
│   │       ├── bone_shrine_3.tscn
│   │       ├── bonk_the_living_mountain_1.tscn
│   │       ├── broken_cage_1.tscn
│   │       ├── broken_cage_2.tscn
│   │       ├── broken_cage_3.tscn
│   │       ├── broken_cage_4.tscn
│   │       ├── broken_cage_5.tscn
│   │       ├── broken_circle_of_wind_1.tscn
│   │       ├── broken_circle_of_wind_2.tscn
│   │       ├── broken_circle_of_wind_3.tscn
│   │       ├── broken_circle_of_wind_4.tscn
│   │       ├── broken_circle_of_wind_5.tscn
│   │       ├── broken_fire_pit_1.tscn
│   │       ├── broken_fire_pit_2.tscn
│   │       ├── broken_fire_pit_3.tscn
│   │       ├── broken_fire_pit_4.tscn
│   │       ├── broken_fire_pit_5.tscn
│   │       ├── broken_lightning_rod_1.tscn
│   │       ├── broken_lightning_rod_2.tscn
│   │       ├── broken_lightning_rod_3.tscn
│   │       ├── broken_lightning_rod_4.tscn
│   │       ├── broken_lightning_rod_5.tscn
│   │       ├── bronze_dragon_roost_1.tscn
│   │       ├── buried_soul_1.tscn
│   │       ├── buried_soul_2.tscn
│   │       ├── buried_soul_3.tscn
│   │       ├── buried_soul_4.tscn
│   │       ├── burning_watchtower_1.tscn
│   │       ├── burning_watchtower_2.tscn
│   │       ├── burning_watchtower_3.tscn
│   │       ├── burning_watchtower_4.tscn
│   │       ├── burrow_1.tscn
│   │       ├── burrow_2.tscn
│   │       ├── burrow_3.tscn
│   │       ├── burrow_4.tscn
│   │       ├── caged_fire_1.tscn
│   │       ├── caged_fire_2.tscn
│   │       ├── cenarion_1.tscn
│   │       ├── chaining_storm_1.tscn
│   │       ├── chaos_warlock_1.tscn
│   │       ├── chaos_warlock_2.tscn
│   │       ├── charged_obelisk_1.tscn
│   │       ├── chilled_spire_1.tscn
│   │       ├── chilled_spire_2.tscn
│   │       ├── cloud_warrior_1.tscn
│   │       ├── cloud_warrior_2.tscn
│   │       ├── cloud_warrior_3.tscn
│   │       ├── cloud_warrior_4.tscn
│   │       ├── cloud_warrior_5.tscn
│   │       ├── cloudy_temple_of_absorption_1.tscn
│   │       ├── coconut_sapling_1.tscn
│   │       ├── coconut_sapling_2.tscn
│   │       ├── coin_machine_1.tscn
│   │       ├── coin_machine_2.tscn
│   │       ├── cold_obelisk_1.tscn
│   │       ├── cold_obelisk_2.tscn
│   │       ├── cold_obelisk_3.tscn
│   │       ├── cold_troll_1.tscn
│   │       ├── cold_troll_2.tscn
│   │       ├── cold_troll_3.tscn
│   │       ├── cold_troll_4.tscn
│   │       ├── contraption_1.tscn
│   │       ├── contraption_2.tscn
│   │       ├── contraption_3.tscn
│   │       ├── contraption_4.tscn
│   │       ├── crimson_wyrm_1.tscn
│   │       ├── cruel_fire_1.tscn
│   │       ├── cruel_fire_2.tscn
│   │       ├── cruel_fire_3.tscn
│   │       ├── cursed_grounds_1.tscn
│   │       ├── cursed_grounds_2.tscn
│   │       ├── cursed_grounds_3.tscn
│   │       ├── cute_small_spider_1.tscn
│   │       ├── cute_small_spider_2.tscn
│   │       ├── cute_small_spider_3.tscn
│   │       ├── cute_small_spider_4.tscn
│   │       ├── dark_battery_1.tscn
│   │       ├── dark_battery_2.tscn
│   │       ├── dark_battery_3.tscn
│   │       ├── dark_fire_pit_1.tscn
│   │       ├── dark_fire_pit_2.tscn
│   │       ├── dark_fire_pit_3.tscn
│   │       ├── dark_fire_pit_4.tscn
│   │       ├── dark_fire_pit_5.tscn
│   │       ├── death_knight_1.tscn
│   │       ├── dimensional_flux_collector_1.tscn
│   │       ├── dragon_sorcerer_1.tscn
│   │       ├── drake_whisperer_1.tscn
│   │       ├── dreadlord_1.tscn
│   │       ├── dutchmans_grave_1.tscn
│   │       ├── dwarven_forgery_1.tscn
│   │       ├── ebonfrost_crystal_1.tscn
│   │       ├── embershell_turtle_hatchling_1.tscn
│   │       ├── embershell_turtle_hatchling_2.tscn
│   │       ├── embershell_turtle_hatchling_3.tscn
│   │       ├── embershell_turtle_hatchling_4.tscn
│   │       ├── embershell_turtle_hatchling_5.tscn
│   │       ├── energy_junction_1.tscn
│   │       ├── energy_junction_2.tscn
│   │       ├── energy_junction_3.tscn
│   │       ├── essence_of_fury_1.tscn
│   │       ├── essence_of_fury_2.tscn
│   │       ├── essence_of_fury_3.tscn
│   │       ├── essence_of_fury_4.tscn
│   │       ├── essence_of_fury_5.tscn
│   │       ├── felweed_1.tscn
│   │       ├── felweed_2.tscn
│   │       ├── felweed_3.tscn
│   │       ├── felweed_4.tscn
│   │       ├── felweed_5.tscn
│   │       ├── felweed_6.tscn
│   │       ├── fenced_flames_1.tscn
│   │       ├── fenced_flames_2.tscn
│   │       ├── fenced_flames_3.tscn
│   │       ├── fenced_flames_4.tscn
│   │       ├── fiery_dog_1.tscn
│   │       ├── fiery_dog_2.tscn
│   │       ├── fiery_dog_3.tscn
│   │       ├── fiery_dog_4.tscn
│   │       ├── fiery_dog_5.tscn
│   │       ├── fiery_pebble_1.tscn
│   │       ├── fiery_pebble_2.tscn
│   │       ├── fiery_pebble_3.tscn
│   │       ├── fiery_pebble_4.tscn
│   │       ├── fiery_pebble_5.tscn
│   │       ├── fiery_pebble_6.tscn
│   │       ├── fire_battery_1.tscn
│   │       ├── fire_battery_2.tscn
│   │       ├── fire_battery_3.tscn
│   │       ├── fire_star_1.tscn
│   │       ├── firestorm_cell_1.tscn
│   │       ├── firestorm_cell_2.tscn
│   │       ├── firestorm_cell_3.tscn
│   │       ├── firestorm_cell_4.tscn
│   │       ├── fisherman_1.tscn
│   │       ├── forest_archer_1.tscn
│   │       ├── forest_archer_2.tscn
│   │       ├── forest_archer_3.tscn
│   │       ├── forest_protectress_1.tscn
│   │       ├── forest_troll_1.tscn
│   │       ├── forest_troll_2.tscn
│   │       ├── forest_troll_3.tscn
│   │       ├── frost_root_1.tscn
│   │       ├── frost_root_2.tscn
│   │       ├── frost_root_3.tscn
│   │       ├── frost_root_4.tscn
│   │       ├── frost_root_5.tscn
│   │       ├── frost_root_6.tscn
│   │       ├── frosty_rock_1.tscn
│   │       ├── frosty_rock_2.tscn
│   │       ├── frosty_rock_3.tscn
│   │       ├── frosty_rock_4.tscn
│   │       ├── frozen_well_1.tscn
│   │       ├── garden_of_eden_1.tscn
│   │       ├── gatling_gun_1.tscn
│   │       ├── genis_sage_1.tscn
│   │       ├── geothermal_extractor_1.tscn
│   │       ├── geothermal_extractor_2.tscn
│   │       ├── glaive_master_1.tscn
│   │       ├── glowing_solar_orb_1.tscn
│   │       ├── glowing_solar_orb_2.tscn
│   │       ├── glowing_solar_orb_3.tscn
│   │       ├── glowing_solar_orb_4.tscn
│   │       ├── glowing_solar_orb_5.tscn
│   │       ├── gnoll_thunder_mage_1.tscn
│   │       ├── gnoll_thunder_mage_2.tscn
│   │       ├── gnoll_thunder_mage_3.tscn
│   │       ├── goblin_stronghold_1.tscn
│   │       ├── grab-o-bot_1.tscn
│   │       ├── green_dragon_roost_1.tscn
│   │       ├── green_lightning_1.tscn
│   │       ├── green_lightning_2.tscn
│   │       ├── green_lightning_3.tscn
│   │       ├── green_lightning_4.tscn
│   │       ├── greyfang_1.tscn
│   │       ├── gryphon_rider_1.tscn
│   │       ├── hall_of_souls_1.tscn
│   │       ├── hall_of_souls_2.tscn
│   │       ├── hall_of_souls_3.tscn
│   │       ├── harby_1.tscn
│   │       ├── harpy_witch_1.tscn
│   │       ├── harpy_witch_2.tscn
│   │       ├── haunted_rubble_1.tscn
│   │       ├── haunted_rubble_2.tscn
│   │       ├── haunted_rubble_3.tscn
│   │       ├── haunted_rubble_4.tscn
│   │       ├── haunted_rubble_5.tscn
│   │       ├── healing_obelisk_1.tscn
│   │       ├── healing_obelisk_2.tscn
│   │       ├── healing_obelisk_3.tscn
│   │       ├── healing_obelisk_4.tscn
│   │       ├── helicopter_zone_1.tscn
│   │       ├── hell_bat_1.tscn
│   │       ├── hell_bat_2.tscn
│   │       ├── hell_bat_3.tscn
│   │       ├── holy_energy_1.tscn
│   │       ├── ice_battery_1.tscn
│   │       ├── ice_battery_2.tscn
│   │       ├── ice_battery_3.tscn
│   │       ├── icy_core_1.tscn
│   │       ├── icy_core_2.tscn
│   │       ├── icy_skulls_1.tscn
│   │       ├── icy_skulls_2.tscn
│   │       ├── icy_skulls_3.tscn
│   │       ├── icy_skulls_4.tscn
│   │       ├── icy_spirit_1.tscn
│   │       ├── icy_spirit_2.tscn
│   │       ├── icy_spirit_3.tscn
│   │       ├── igloo_1.tscn
│   │       ├── igloo_2.tscn
│   │       ├── igloo_3.tscn
│   │       ├── inexperienced_huntress_1.tscn
│   │       ├── inexperienced_huntress_2.tscn
│   │       ├── inexperienced_huntress_3.tscn
│   │       ├── inflamed_stone_1.tscn
│   │       ├── inflamed_stone_2.tscn
│   │       ├── inflamed_stone_3.tscn
│   │       ├── initiate_elementalist_1.tscn
│   │       ├── initiate_elementalist_2.tscn
│   │       ├── initiate_elementalist_3.tscn
│   │       ├── initiate_elementalist_4.tscn
│   │       ├── it_1.tscn
│   │       ├── jungle_stalker_1.tscn
│   │       ├── jungle_stalker_2.tscn
│   │       ├── jungle_stalker_3.tscn
│   │       ├── kraken_1.tscn
│   │       ├── lesser_astral_defender_1.tscn
│   │       ├── lesser_astral_defender_2.tscn
│   │       ├── lesser_astral_defender_3.tscn
│   │       ├── lesser_astral_defender_4.tscn
│   │       ├── lesser_astral_defender_5.tscn
│   │       ├── lesser_dark_defender_1.tscn
│   │       ├── lesser_dark_defender_2.tscn
│   │       ├── lesser_dark_defender_3.tscn
│   │       ├── lesser_dark_defender_4.tscn
│   │       ├── lesser_dark_defender_5.tscn
│   │       ├── lesser_elemental_ghost_1.tscn
│   │       ├── lesser_elemental_ghost_2.tscn
│   │       ├── lesser_elemental_ghost_3.tscn
│   │       ├── lesser_elemental_ghost_4.tscn
│   │       ├── lesser_elemental_ghost_5.tscn
│   │       ├── lesser_flamy_defender_1.tscn
│   │       ├── lesser_flamy_defender_2.tscn
│   │       ├── lesser_flamy_defender_3.tscn
│   │       ├── lesser_flamy_defender_4.tscn
│   │       ├── lesser_flamy_defender_5.tscn
│   │       ├── lesser_ice_defender_1.tscn
│   │       ├── lesser_ice_defender_2.tscn
│   │       ├── lesser_ice_defender_3.tscn
│   │       ├── lesser_ice_defender_4.tscn
│   │       ├── lesser_ice_defender_5.tscn
│   │       ├── lesser_iron_defender_1.tscn
│   │       ├── lesser_iron_defender_2.tscn
│   │       ├── lesser_iron_defender_3.tscn
│   │       ├── lesser_iron_defender_4.tscn
│   │       ├── lesser_iron_defender_5.tscn
│   │       ├── lesser_natural_defender_1.tscn
│   │       ├── lesser_natural_defender_2.tscn
│   │       ├── lesser_natural_defender_3.tscn
│   │       ├── lesser_natural_defender_4.tscn
│   │       ├── lesser_natural_defender_5.tscn
│   │       ├── lesser_priest_1.tscn
│   │       ├── lesser_priest_2.tscn
│   │       ├── lesser_priest_3.tscn
│   │       ├── lesser_priest_4.tscn
│   │       ├── lesser_priest_5.tscn
│   │       ├── lesser_skeletal_mage_1.tscn
│   │       ├── lesser_skeletal_mage_2.tscn
│   │       ├── lesser_skeletal_mage_3.tscn
│   │       ├── lesser_skeletal_mage_4.tscn
│   │       ├── lesser_storm_defender_1.tscn
│   │       ├── lesser_storm_defender_2.tscn
│   │       ├── lesser_storm_defender_3.tscn
│   │       ├── lesser_storm_defender_4.tscn
│   │       ├── lesser_storm_defender_5.tscn
│   │       ├── lesser_wolves_den_1.tscn
│   │       ├── lesser_wolves_den_2.tscn
│   │       ├── lesser_wolves_den_3.tscn
│   │       ├── library_of_alexandria_1.tscn
│   │       ├── lich_king_1.tscn
│   │       ├── lightning_eye_1.tscn
│   │       ├── lightning_generator_1.tscn
│   │       ├── lightning_generator_2.tscn
│   │       ├── lightning_generator_3.tscn
│   │       ├── lightning_generator_4.tscn
│   │       ├── lightning_totem_1.tscn
│   │       ├── lightning_totem_2.tscn
│   │       ├── lightning_totem_3.tscn
│   │       ├── little_phoenix_1.tscn
│   │       ├── little_phoenix_2.tscn
│   │       ├── little_phoenix_3.tscn
│   │       ├── living_volcano_1.tscn
│   │       ├── lunar_emitter_1.tscn
│   │       ├── lunar_emitter_2.tscn
│   │       ├── lunar_sentinel_1.tscn
│   │       ├── lunar_sentinel_2.tscn
│   │       ├── lunar_sentinel_3.tscn
│   │       ├── lunar_sentinel_4.tscn
│   │       ├── magic_battery_1.tscn
│   │       ├── magic_battery_2.tscn
│   │       ├── magic_battery_3.tscn
│   │       ├── magic_mushroom_1.tscn
│   │       ├── magna_warrior_1.tscn
│   │       ├── magna_warrior_2.tscn
│   │       ├── magna_warrior_3.tscn
│   │       ├── magna_warrior_4.tscn
│   │       ├── magna_warrior_5.tscn
│   │       ├── mana-touched_drake_1.tscn
│   │       ├── mana-touched_drake_2.tscn
│   │       ├── mana-touched_drake_3.tscn
│   │       ├── mana-touched_drake_4.tscn
│   │       ├── marine_1.tscn
│   │       ├── marine_2.tscn
│   │       ├── meteor_totem_1.tscn
│   │       ├── militia_watchtower_1.tscn
│   │       ├── militia_watchtower_2.tscn
│   │       ├── militia_watchtower_3.tscn
│   │       ├── militia_watchtower_4.tscn
│   │       ├── miner_1.tscn
│   │       ├── miner_2.tscn
│   │       ├── miner_3.tscn
│   │       ├── minor_magic_ruin_1.tscn
│   │       ├── minor_magic_ruin_2.tscn
│   │       ├── minor_magic_ruin_3.tscn
│   │       ├── minor_magic_ruin_4.tscn
│   │       ├── minor_magic_ruin_5.tscn
│   │       ├── minor_magic_ruin_6.tscn
│   │       ├── mister_fireflies_1.tscn
│   │       ├── mister_fireflies_2.tscn
│   │       ├── mister_fireflies_3.tscn
│   │       ├── monolith_of_chaos_1.tscn
│   │       ├── morphling_1.tscn
│   │       ├── mossy_acid_sprayer_1.tscn
│   │       ├── mossy_acid_sprayer_2.tscn
│   │       ├── mossy_acid_sprayer_3.tscn
│   │       ├── mossy_acid_sprayer_4.tscn
│   │       ├── mossy_acid_sprayer_5.tscn
│   │       ├── mud_golem_1.tscn
│   │       ├── nature_sprites_1.tscn
│   │       ├── nature_sprites_2.tscn
│   │       ├── nature_sprites_3.tscn
│   │       ├── necromantic_altar_1.tscn
│   │       ├── necromantic_altar_2.tscn
│   │       ├── necromantic_altar_3.tscn
│   │       ├── necromantic_altar_4.tscn
│   │       ├── nortrom_the_silencer_1.tscn
│   │       ├── nuclear_missile_launcher_1.tscn
│   │       ├── obelisk_of_fortuity_1.tscn
│   │       ├── obelisk_of_fortuity_2.tscn
│   │       ├── obelisk_of_fortuity_3.tscn
│   │       ├── obelisk_of_fortuity_4.tscn
│   │       ├── obelisk_of_fortuity_5.tscn
│   │       ├── owl_of_wisdom_1.tscn
│   │       ├── owl_of_wisdom_2.tscn
│   │       ├── particle_accelerator_1.tscn
│   │       ├── particle_accelerator_2.tscn
│   │       ├── particle_accelerator_3.tscn
│   │       ├── phantom_1.tscn
│   │       ├── phantom_2.tscn
│   │       ├── phantom_3.tscn
│   │       ├── phantom_4.tscn
│   │       ├── phantom_5.tscn
│   │       ├── plagued_crypt_1.tscn
│   │       ├── planar_gate_1.tscn
│   │       ├── poison_battery_1.tscn
│   │       ├── poison_battery_2.tscn
│   │       ├── poison_battery_3.tscn
│   │       ├── polar_bear_cub_1.tscn
│   │       ├── polar_bear_cub_2.tscn
│   │       ├── polar_bear_cub_3.tscn
│   │       ├── portal_to_swine_purgatory_1.tscn
│   │       ├── portal_to_swine_purgatory_2.tscn
│   │       ├── portal_to_swine_purgatory_3.tscn
│   │       ├── prince_of_lightning_1.tscn
│   │       ├── prince_of_lightning_2.tscn
│   │       ├── princess_of_light_1.tscn
│   │       ├── princess_of_light_2.tscn
│   │       ├── razorboar_thornweaver_1.tscn
│   │       ├── razorboar_thornweaver_2.tscn
│   │       ├── razorboar_thornweaver_3.tscn
│   │       ├── red_ball_lightning_1.tscn
│   │       ├── red_ball_lightning_2.tscn
│   │       ├── regenerating_well_1.tscn
│   │       ├── regenerating_well_2.tscn
│   │       ├── regenerating_well_3.tscn
│   │       ├── rooted_chasm_1.tscn
│   │       ├── rooted_chasm_2.tscn
│   │       ├── rooted_chasm_3.tscn
│   │       ├── rooted_chasm_4.tscn
│   │       ├── rotted_flashing_grave_1.tscn
│   │       ├── rotted_flashing_grave_2.tscn
│   │       ├── rotted_flashing_grave_3.tscn
│   │       ├── rotted_flashing_grave_4.tscn
│   │       ├── rotted_flashing_grave_5.tscn
│   │       ├── rotted_flashing_grave_6.tscn
│   │       ├── rowing_boat_1.tscn
│   │       ├── rowing_boat_2.tscn
│   │       ├── rowing_boat_3.tscn
│   │       ├── rowing_boat_4.tscn
│   │       ├── ruined_monolith_1.tscn
│   │       ├── ruined_monolith_2.tscn
│   │       ├── ruined_monolith_3.tscn
│   │       ├── ruined_monolith_4.tscn
│   │       ├── ruined_monolith_5.tscn
│   │       ├── ruined_monolith_6.tscn
│   │       ├── ruined_storm_cap_1.tscn
│   │       ├── ruined_storm_cap_2.tscn
│   │       ├── ruined_storm_cap_3.tscn
│   │       ├── ruined_storm_cap_4.tscn
│   │       ├── ruined_storm_cap_5.tscn
│   │       ├── ruined_storm_cap_6.tscn
│   │       ├── ruined_sun_pedestal_1.tscn
│   │       ├── ruined_sun_pedestal_2.tscn
│   │       ├── ruined_sun_pedestal_3.tscn
│   │       ├── ruined_sun_pedestal_4.tscn
│   │       ├── ruined_sun_pedestal_5.tscn
│   │       ├── ruined_sun_pedestal_6.tscn
│   │       ├── ruined_sun_pedestal_7.tscn
│   │       ├── ruined_wind_tower_1.tscn
│   │       ├── ruined_wind_tower_2.tscn
│   │       ├── ruined_wind_tower_3.tscn
│   │       ├── ruined_wind_tower_4.tscn
│   │       ├── rundown_iron_sentry_1.tscn
│   │       ├── rundown_iron_sentry_2.tscn
│   │       ├── rundown_iron_sentry_3.tscn
│   │       ├── sacred_altar_1.tscn
│   │       ├── sacrificial_lamb_1.tscn
│   │       ├── sacrificial_lamb_2.tscn
│   │       ├── safirons_cold_grave_1.tscn
│   │       ├── scales_1.tscn
│   │       ├── sea_turtle_1.tscn
│   │       ├── sea_turtle_2.tscn
│   │       ├── sea_turtle_3.tscn
│   │       ├── servant_of_the_twin_flames_1.tscn
│   │       ├── servant_of_the_twin_flames_2.tscn
│   │       ├── sewer_connection_1.tscn
│   │       ├── sewer_connection_2.tscn
│   │       ├── sewer_connection_3.tscn
│   │       ├── sewer_connection_4.tscn
│   │       ├── shadow_1.tscn
│   │       ├── shaman_1.tscn
│   │       ├── shaman_2.tscn
│   │       ├── shaman_3.tscn
│   │       ├── shard_of_souls_1.tscn
│   │       ├── shard_of_souls_2.tscn
│   │       ├── silver_knight_1.tscn
│   │       ├── silver_knight_2.tscn
│   │       ├── skink_1.tscn
│   │       ├── skink_2.tscn
│   │       ├── skink_3.tscn
│   │       ├── skink_4.tscn
│   │       ├── skink_5.tscn
│   │       ├── small_brazier_1.tscn
│   │       ├── small_brazier_2.tscn
│   │       ├── small_brazier_3.tscn
│   │       ├── small_brazier_4.tscn
│   │       ├── small_bug_nest_1.tscn
│   │       ├── small_bug_nest_2.tscn
│   │       ├── small_bug_nest_3.tscn
│   │       ├── small_bug_nest_4.tscn
│   │       ├── small_cactus_1.tscn
│   │       ├── small_cactus_2.tscn
│   │       ├── small_cactus_3.tscn
│   │       ├── small_cactus_4.tscn
│   │       ├── small_cactus_5.tscn
│   │       ├── small_cactus_6.tscn
│   │       ├── small_fire_sprayer_1.tscn
│   │       ├── small_fire_sprayer_2.tscn
│   │       ├── small_fire_sprayer_3.tscn
│   │       ├── small_fire_sprayer_4.tscn
│   │       ├── small_fire_sprayer_5.tscn
│   │       ├── small_fire_sprayer_6.tscn
│   │       ├── small_frost_fire_1.tscn
│   │       ├── small_frost_fire_2.tscn
│   │       ├── small_frost_fire_3.tscn
│   │       ├── small_frost_fire_4.tscn
│   │       ├── small_frost_fire_5.tscn
│   │       ├── small_frozen_mushroom_1.tscn
│   │       ├── small_frozen_mushroom_2.tscn
│   │       ├── small_frozen_mushroom_3.tscn
│   │       ├── small_frozen_mushroom_4.tscn
│   │       ├── small_frozen_mushroom_5.tscn
│   │       ├── small_ice_mine_1.tscn
│   │       ├── small_ice_mine_2.tscn
│   │       ├── small_ice_mine_3.tscn
│   │       ├── small_ice_mine_4.tscn
│   │       ├── small_light_1.tscn
│   │       ├── small_light_2.tscn
│   │       ├── small_light_3.tscn
│   │       ├── small_light_4.tscn
│   │       ├── small_light_5.tscn
│   │       ├── small_pocket_rocket_1.tscn
│   │       ├── small_pocket_rocket_2.tscn
│   │       ├── small_pocket_rocket_3.tscn
│   │       ├── small_pocket_rocket_4.tscn
│   │       ├── small_pocket_rocket_5.tscn
│   │       ├── small_ray_blaster_1.tscn
│   │       ├── small_ray_blaster_2.tscn
│   │       ├── small_ray_blaster_3.tscn
│   │       ├── small_ray_blaster_4.tscn
│   │       ├── small_ray_blaster_5.tscn
│   │       ├── small_serpent_ward_1.tscn
│   │       ├── small_serpent_ward_2.tscn
│   │       ├── small_serpent_ward_3.tscn
│   │       ├── small_serpent_ward_4.tscn
│   │       ├── small_torch_1.tscn
│   │       ├── small_torch_2.tscn
│   │       ├── small_torch_3.tscn
│   │       ├── small_torch_4.tscn
│   │       ├── small_torch_5.tscn
│   │       ├── sniper_1.tscn
│   │       ├── sniper_2.tscn
│   │       ├── sniper_3.tscn
│   │       ├── sniper_4.tscn
│   │       ├── snowy_pebble_1.tscn
│   │       ├── snowy_pebble_2.tscn
│   │       ├── snowy_pebble_3.tscn
│   │       ├── snowy_pebble_4.tscn
│   │       ├── snowy_pebble_5.tscn
│   │       ├── snowy_pebble_6.tscn
│   │       ├── solar_collector_1.tscn
│   │       ├── solar_collector_2.tscn
│   │       ├── solar_emitter_1.tscn
│   │       ├── solar_emitter_2.tscn
│   │       ├── sorceress_1.tscn
│   │       ├── soul_vault_1.tscn
│   │       ├── soulflame_device_1.tscn
│   │       ├── spell_collector_1.tscn
│   │       ├── spell_collector_2.tscn
│   │       ├── spider_queen_1.tscn
│   │       ├── star_gazer_1.tscn
│   │       ├── star_gazer_2.tscn
│   │       ├── star_gazer_3.tscn
│   │       ├── star_gazer_4.tscn
│   │       ├── storm_battery_1.tscn
│   │       ├── storm_battery_2.tscn
│   │       ├── storm_battery_3.tscn
│   │       ├── storm_coil_1.tscn
│   │       ├── storm_focus_1.tscn
│   │       ├── stormy_dog_1.tscn
│   │       ├── stormy_dog_2.tscn
│   │       ├── stormy_dog_3.tscn
│   │       ├── stormy_dog_4.tscn
│   │       ├── stormy_dog_5.tscn
│   │       ├── sun_crusader_1.tscn
│   │       ├── sun_crusader_2.tscn
│   │       ├── taita_the_hermit_1.tscn
│   │       ├── teacher_1.tscn
│   │       ├── teacher_2.tscn
│   │       ├── teacher_3.tscn
│   │       ├── teacher_4.tscn
│   │       ├── teacher_5.tscn
│   │       ├── teacher_6.tscn
│   │       ├── tentacle_spawn_1.tscn
│   │       ├── tentacle_spawn_2.tscn
│   │       ├── tentacle_spawn_3.tscn
│   │       ├── tentacle_spawn_4.tscn
│   │       ├── tentacle_spawn_5.tscn
│   │       ├── tentacle_spawn_6.tscn
│   │       ├── the_conduit_1.tscn
│   │       ├── the_council_of_demons_1.tscn
│   │       ├── the_fire_lord_1.tscn
│   │       ├── the_frozen_wyrm_1.tscn
│   │       ├── the_furnace_1.tscn
│   │       ├── the_omnislasher_1.tscn
│   │       ├── the_steam_engine_1.tscn
│   │       ├── thief_apprentice_1.tscn
│   │       ├── thief_apprentice_2.tscn
│   │       ├── thief_apprentice_3.tscn
│   │       ├── thief_apprentice_4.tscn
│   │       ├── thief_apprentice_5.tscn
│   │       ├── tidewater_stream_1.tscn
│   │       ├── time_manipulator_1.tscn
│   │       ├── timevault_1.tscn
│   │       ├── tiny_shrub_1.tscn
│   │       ├── tiny_shrub_2.tscn
│   │       ├── tiny_shrub_3.tscn
│   │       ├── tiny_shrub_4.tscn
│   │       ├── tiny_shrub_5.tscn
│   │       ├── tiny_shrub_6.tscn
│   │       ├── tiny_storm_lantern_1.tscn
│   │       ├── tiny_storm_lantern_2.tscn
│   │       ├── tiny_storm_lantern_3.tscn
│   │       ├── tiny_storm_lantern_4.tscn
│   │       ├── tombstone_1.tscn
│   │       ├── tombstone_2.tscn
│   │       ├── tombstone_3.tscn
│   │       ├── tombstone_4.tscn
│   │       ├── tombstone_5.tscn
│   │       ├── tombstone_6.tscn
│   │       ├── trash_heap_1.tscn
│   │       ├── trash_heap_2.tscn
│   │       ├── trash_heap_3.tscn
│   │       ├── trash_heap_4.tscn
│   │       ├── trash_heap_5.tscn
│   │       ├── trash_heap_6.tscn
│   │       ├── tree_stump_1.tscn
│   │       ├── tree_stump_2.tscn
│   │       ├── tree_stump_3.tscn
│   │       ├── tree_stump_4.tscn
│   │       ├── tree_stump_5.tscn
│   │       ├── tundra_stalker_1.tscn
│   │       ├── tundra_stalker_2.tscn
│   │       ├── tundra_stalker_3.tscn
│   │       ├── tundra_stalker_4.tscn
│   │       ├── tundra_stalker_5.tscn
│   │       ├── undisturbed_crypt_1.tscn
│   │       ├── undisturbed_crypt_2.tscn
│   │       ├── undisturbed_crypt_3.tscn
│   │       ├── undisturbed_crypt_4.tscn
│   │       ├── valor_1.tscn
│   │       ├── village_witch_1.tscn
│   │       ├── village_witch_2.tscn
│   │       ├── village_witch_3.tscn
│   │       ├── village_witch_4.tscn
│   │       ├── void_drake_1.tscn
│   │       ├── void_drake_2.tscn
│   │       ├── vulshok_the_berserker_1.tscn
│   │       ├── warrior_of_light_1.tscn
│   │       ├── warrior_of_light_2.tscn
│   │       ├── warrior_of_light_3.tscn
│   │       ├── wild_warbeast_1.tscn
│   │       ├── witch_doctor_1.tscn
│   │       ├── wooden_trap_1.tscn
│   │       ├── wooden_trap_2.tscn
│   │       ├── wooden_trap_3.tscn
│   │       ├── wooden_trap_4.tscn
│   │       ├── wooden_trap_5.tscn
│   │       ├── xeno_research_facility_1.tscn
│   │       ├── ymir_1.tscn
│   │       ├── young_northern_troll_1.tscn
│   │       ├── young_northern_troll_2.tscn
│   │       ├── young_northern_troll_3.tscn
│   │       ├── zealot_1.tscn
│   │       ├── zealot_2.tscn
│   │       ├── zealot_3.tscn
│   │       ├── zealot_4.tscn
│   │       └── zeus_1.tscn
│   ├── ui/
│   │   ├── buttons/
│   │   │   ├── ability_button.gd
│   │   │   ├── ability_button.tscn
│   │   │   ├── auto_mode_indicator.gd
│   │   │   ├── auto_mode_indicator.tscn
│   │   │   ├── autocast_button.gd
│   │   │   ├── autocast_button.tscn
│   │   │   ├── buff_group_button.gd
│   │   │   ├── buff_group_button.tscn
│   │   │   ├── builder_button.tscn
│   │   │   ├── button_tooltip.gd
│   │   │   ├── button_tooltip.tscn
│   │   │   ├── button_with_rich_tooltip.gd
│   │   │   ├── element_button.gd
│   │   │   ├── element_button.tscn
│   │   │   ├── empty_unit_button.gd
│   │   │   ├── empty_unit_button.tscn
│   │   │   ├── freshness_indicator.gd
│   │   │   ├── freshness_indicator.tscn
│   │   │   ├── inventory_slot_button.tscn
│   │   │   ├── item_button.gd
│   │   │   ├── item_button.tscn
│   │   │   ├── item_button_inner.gd
│   │   │   ├── menu_expanding_button.gd
│   │   │   ├── menu_expanding_button.tscn
│   │   │   ├── rarity_background.gd
│   │   │   ├── rarity_background.tscn
│   │   │   ├── recipe_button.gd
│   │   │   ├── recipe_button.tscn
│   │   │   ├── speed_button.tscn
│   │   │   ├── time_indicator.gd
│   │   │   ├── time_indicator.tscn
│   │   │   ├── tower_button.gd
│   │   │   ├── tower_button.tscn
│   │   │   ├── wisdom_upgrade_button.gd
│   │   │   └── wisdom_upgrade_button.tscn
│   │   ├── dev_controls/
│   │   │   ├── dev_controls.gd
│   │   │   ├── dev_controls.tscn
│   │   │   ├── signals_control.gd
│   │   │   ├── signals_control.tscn
│   │   │   ├── wave_control.gd
│   │   │   └── wave_control.tscn
│   │   ├── filter_buttons/
│   │   │   ├── element_filter.gd
│   │   │   ├── element_filter.tscn
│   │   │   ├── filter_button.tscn
│   │   │   ├── filter_button_element.gd
│   │   │   ├── filter_button_element.tscn
│   │   │   ├── filter_button_item_type.gd
│   │   │   ├── filter_button_item_type.tscn
│   │   │   ├── filter_button_rarity.gd
│   │   │   ├── filter_button_rarity.tscn
│   │   │   ├── item_type_filter.gd
│   │   │   ├── item_type_filter.tscn
│   │   │   ├── rarity_filter.gd
│   │   │   └── rarity_filter.tscn
│   │   ├── game_menu/
│   │   │   ├── credits_menu.gd
│   │   │   ├── credits_menu.tscn
│   │   │   ├── game_menu.gd
│   │   │   ├── game_menu.tscn
│   │   │   ├── help_menu.gd
│   │   │   ├── help_menu.tscn
│   │   │   ├── help_menu_tab.gd
│   │   │   ├── help_menu_tab.tscn
│   │   │   ├── settings_menu.gd
│   │   │   └── settings_menu.tscn
│   │   ├── hud/
│   │   │   ├── OneTimeHelpPopup.tscn
│   │   │   ├── build_version_label.gd
│   │   │   ├── build_version_label.tscn
│   │   │   ├── builder_menu.gd
│   │   │   ├── builder_menu.tscn
│   │   │   ├── combat_log_window.gd
│   │   │   ├── combat_log_window.tscn
│   │   │   ├── desync_indicator.tscn
│   │   │   ├── elements_menu.gd
│   │   │   ├── elements_menu.tscn
│   │   │   ├── floating_text.gd
│   │   │   ├── floating_text.tscn
│   │   │   ├── flying_item.gd
│   │   │   ├── flying_item.tscn
│   │   │   ├── game_speed_controller.gd
│   │   │   ├── game_speed_controller.tscn
│   │   │   ├── hud.gd
│   │   │   ├── hud.tscn
│   │   │   ├── label_with_rich_tooltip.gd
│   │   │   ├── mission_track_indicator.gd
│   │   │   ├── mission_track_indicator.tscn
│   │   │   ├── mission_tracker_container.gd
│   │   │   ├── mission_tracker_container.tscn
│   │   │   ├── movable_window.gd
│   │   │   ├── movable_window.tscn
│   │   │   ├── multiplayer_pause_indicator.tscn
│   │   │   ├── one_time_help_popup.gd
│   │   │   ├── rich_text_label_with_rich_tooltip.gd
│   │   │   ├── texture_rect_with_rich_tooltip.gd
│   │   │   ├── tutorial_menu.gd
│   │   │   └── tutorial_menu.tscn
│   │   ├── item_stash_menu/
│   │   │   ├── item_stash_menu.gd
│   │   │   └── item_stash_menu.tscn
│   │   ├── player_resource_display/
│   │   │   ├── player_resource_display.gd
│   │   │   ├── player_resource_display.tscn
│   │   │   ├── resource_status_panel.gd
│   │   │   └── resource_status_panel.tscn
│   │   ├── title_screen/
│   │   │   ├── configure_singleplayer_menu.gd
│   │   │   ├── configure_singleplayer_menu.tscn
│   │   │   ├── connecting_to_server_indicator.tscn
│   │   │   ├── encyclopedia_generic_tab.gd
│   │   │   ├── encyclopedia_generic_tab.tscn
│   │   │   ├── encyclopedia_items.gd
│   │   │   ├── encyclopedia_items.tscn
│   │   │   ├── encyclopedia_menu.gd
│   │   │   ├── encyclopedia_menu.tscn
│   │   │   ├── encyclopedia_towers.gd
│   │   │   ├── encyclopedia_towers.tscn
│   │   │   ├── export_exp_menu.gd
│   │   │   ├── export_exp_menu.tscn
│   │   │   ├── import_exp_menu.gd
│   │   │   ├── import_exp_menu.tscn
│   │   │   ├── lan_match/
│   │   │   │   ├── create_lan_match_menu.gd
│   │   │   │   ├── create_lan_match_menu.tscn
│   │   │   │   ├── lan_connect_menu.gd
│   │   │   │   ├── lan_connect_menu.tscn
│   │   │   │   ├── lan_lobby_menu.gd
│   │   │   │   ├── lan_lobby_menu.tscn
│   │   │   │   ├── setup_lan_game.gd
│   │   │   │   └── setup_lan_game.tscn
│   │   │   ├── match_config.gd
│   │   │   ├── match_config_panel.gd
│   │   │   ├── match_config_panel.tscn
│   │   │   ├── message_popup.gd
│   │   │   ├── message_popup.tscn
│   │   │   ├── missions_menu/
│   │   │   │   ├── mission_card.gd
│   │   │   │   ├── mission_card.tscn
│   │   │   │   ├── missions_menu.gd
│   │   │   │   ├── missions_menu.tscn
│   │   │   │   ├── missions_menu_tab.gd
│   │   │   │   └── missions_menu_tab.tscn
│   │   │   ├── notification_panel.gd
│   │   │   ├── notification_panel.tscn
│   │   │   ├── online/
│   │   │   │   ├── create_online_match_menu.gd
│   │   │   │   ├── create_online_match_menu.tscn
│   │   │   │   ├── match_card.gd
│   │   │   │   ├── match_card.tscn
│   │   │   │   ├── online_lobby_menu.gd
│   │   │   │   ├── online_lobby_menu.tscn
│   │   │   │   ├── online_match_list_menu.gd
│   │   │   │   ├── online_match_list_menu.tscn
│   │   │   │   ├── setup_online_game.gd
│   │   │   │   └── setup_online_game.tscn
│   │   │   ├── profile_menu.gd
│   │   │   ├── profile_menu.tscn
│   │   │   ├── title_screen.gd
│   │   │   ├── title_screen.tscn
│   │   │   ├── wisdom_upgrade_menu.gd
│   │   │   └── wisdom_upgrade_menu.tscn
│   │   ├── top_left_menu/
│   │   │   ├── game_stats.gd
│   │   │   ├── game_stats.tscn
│   │   │   ├── plus_mode_label.gd
│   │   │   ├── plus_mode_label.tscn
│   │   │   ├── top_left_menu.gd
│   │   │   ├── top_left_menu.tscn
│   │   │   ├── wave_status.gd
│   │   │   └── wave_status.tscn
│   │   ├── tower_stash_menu/
│   │   │   ├── tower_stash_menu.gd
│   │   │   └── tower_stash_menu.tscn
│   │   └── unit_menu/
│   │       ├── buff_container.gd
│   │       ├── buff_container.tscn
│   │       ├── buff_display.gd
│   │       ├── buff_display.tscn
│   │       ├── buff_group_editor.gd
│   │       ├── buff_group_editor.tscn
│   │       ├── creep_details.gd
│   │       ├── creep_details.tscn
│   │       ├── creep_mini_details.gd
│   │       ├── creep_mini_details.tscn
│   │       ├── item_container_panel.gd
│   │       ├── item_container_panel.tscn
│   │       ├── mini_details_label.tscn
│   │       ├── progress_bar_with_label.gd
│   │       ├── progress_bar_with_label.tscn
│   │       ├── tower_details.gd
│   │       ├── tower_details.tscn
│   │       ├── tower_mini_details.gd
│   │       ├── tower_mini_details.tscn
│   │       ├── unit_menu.gd
│   │       └── unit_menu.tscn
│   └── unit/
│       ├── dummy_unit.gd
│       ├── dummy_unit.tscn
│       ├── iterate.gd
│       ├── selection_indicator.gd
│       └── unit.gd
├── tools/
│   ├── README.md
│   ├── check_buff_icons.gd
│   ├── check_rng_sync.gd
│   ├── check_translations.gd
│   ├── check_tscn_paths_in_scripts.gd
│   ├── convert_blender_export.gd
│   ├── convert_tower_scene_to_sprite.gd
│   ├── create_tilesheet.gd
│   ├── cut_single_tile.gd
│   ├── cut_tiles_into_connectors.gd
│   ├── cut_tiles_into_decorations.gd
│   ├── generate_censored_assets.gd
│   ├── pack_sprite_sheet.gd
│   ├── remove_empty_space_tilesheet.gd
│   ├── remove_sheet_margins.gd
│   ├── rename_files.gd
│   ├── render_8_direction_sprites.py
│   ├── separate_tilesheet.gd
│   ├── show_missing_imports.py
│   └── slice_sheet_into_rows.gd
└── webrtc/
    └── README.md
Download .txt
SYMBOL INDEX (23 symbols across 5 files)

FILE: addons/com.heroiclabs.nakama/dotnet-utils/GodotHttpAdapter.cs
  class GodotHttpAdapter (line 30) | public partial class GodotHttpAdapter : Node, IHttpAdapter {
    method SendAsync (line 39) | public async Task<string> SendAsync(string method, Uri uri, IDictionar...
    method IsTransientException (line 106) | private static bool IsTransientException(Exception e) {

FILE: addons/com.heroiclabs.nakama/dotnet-utils/GodotLogger.cs
  class GodotLogger (line 23) | public class GodotLogger : ILogger {
    type LogLevel (line 28) | public enum LogLevel {
    method GodotLogger (line 44) | public GodotLogger(string p_module = "Nakama", LogLevel p_level = LogL...
    method ErrorFormat (line 50) | public void ErrorFormat(string format, params object[] args) {
    method WarnFormat (line 57) | public void WarnFormat(string format, params object[] args) {
    method InfoFormat (line 64) | public void InfoFormat(string format, params object[] args) {
    method DebugFormat (line 71) | public void DebugFormat(string format, params object[] args) {

FILE: addons/com.heroiclabs.nakama/dotnet-utils/GodotWebSocketAdapter.cs
  class GodotWebSocketConnectionException (line 25) | public class GodotWebSocketConnectionException : Exception {
    method GodotWebSocketConnectionException (line 26) | public GodotWebSocketConnectionException(string message = "WebSocket u...
  class GodotWebSocketSendException (line 33) | public class GodotWebSocketSendException : Exception {
    method GodotWebSocketSendException (line 34) | public GodotWebSocketSendException() : base("Unable to send over WebSo...
  class GodotWebSocketAdapter (line 40) | public partial class GodotWebSocketAdapter : Node, ISocketAdapter
    method GodotWebSocketAdapter (line 83) | public GodotWebSocketAdapter()
    method CloseAsync (line 89) | public Task CloseAsync()
    method ConnectAsync (line 100) | public Task ConnectAsync(Uri uri, int timeout)
    method SendAsync (line 130) | public Task SendAsync(ArraySegment<byte> buffer, bool reliable = true,...
    method _Process (line 153) | public override void _Process(double delta)

FILE: tools/render_8_direction_sprites.py
  function render8directions_selected_objects (line 34) | def render8directions_selected_objects(path):
  function get_export_path (line 141) | def get_export_path() -> str:

FILE: tools/show_missing_imports.py
  function print_usage (line 4) | def print_usage():
Condensed preview — 3046 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,178K chars).
[
  {
    "path": ".github/CODEOWNERS",
    "chars": 21,
    "preview": "*   @Kvel2D @Praytic\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 5488,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 2379,
    "preview": "# Contribution guidance\n\n## How to contribute\n\nYou can contribute in different ways:\n\n- Report a bug in Issues\n- Write a"
  },
  {
    "path": ".github/RCLONE.md",
    "chars": 1852,
    "preview": "# Setup rclone\n\nRclone is an advanced way to sync assets between your computer and google drive.\n\nNote that if you're us"
  },
  {
    "path": ".github/TRANSLATING.md",
    "chars": 1585,
    "preview": "# Translation guidance\n\n## How to contribute to translation\n\nTranslated text strings are stored in texts.csv. This file "
  },
  {
    "path": ".github/workflows/github-actions-youtd.yml",
    "chars": 6859,
    "preview": "name: build-and-publish\n\n# NOTE: disabled this export job because it doesn't work\n# with webrtc lib. Webrtc lib files ne"
  },
  {
    "path": ".gitignore",
    "chars": 5822,
    "preview": "# Godot .gitignore config\n#\n# Aims to encompass the most commonly found files that we don't want committed\n# to Git, suc"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2023 Icob2Games\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 1059,
    "preview": "# YouTD 2\n\n![youtd2_logo](https://github.com/user-attachments/assets/ea8a358b-aa12-4d28-9fc5-861bf8d2c497)\n\nYouTD 2 is a"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Nakama.gd",
    "chars": 1950,
    "preview": "@tool\nextends Node\n\n# The default host address of the server.\nconst DEFAULT_HOST : String = \"127.0.0.1\"\n\n# The default p"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/NakamaEvent.gd",
    "chars": 2082,
    "preview": "extends SatoriAsyncResult\n\n# NOTE: renamed from original \"Event\" to avoid name conflicts\nclass_name NakamaEvent\n\n# The n"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/SatoriAPI.gd",
    "chars": 46024,
    "preview": "### Code generated by codegen/main.go. DO NOT EDIT. ###\n\nextends RefCounted\nclass_name SatoriAPI\n\n# Log out a session, i"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/SatoriClient.gd",
    "chars": 7647,
    "preview": "extends RefCounted\n\n## A client for the API in Satori Server.\nclass_name SatoriClient\n\n#region Properties\n\nvar _host\n## "
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/SatoriHttpAdapter.gd",
    "chars": 6246,
    "preview": "@tool\nextends Node\n\n# An adapter which implements the HTTP protocol.\nclass_name SatoriHTTPAdapter\n\n# The logger to use w"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/SatoriSession.gd",
    "chars": 2976,
    "preview": "extends  SatoriAsyncResult\nclass_name SatoriSession\n\nvar _token: String = \"\"\nvar token: String:\n    get:\n        return "
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/utils/SatoriAsyncResult.gd",
    "chars": 695,
    "preview": "extends RefCounted\nclass_name SatoriAsyncResult\n\nvar exception : SatoriException:\n\tset(v):\n\t\tpass\n\tget:\n\t\treturn get_exc"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/utils/SatoriException.gd",
    "chars": 925,
    "preview": "extends RefCounted\n\n# An exception generated during a request.\n# Usually contains at least an error message.\nclass_name "
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/utils/SatoriLogger.gd",
    "chars": 825,
    "preview": "extends RefCounted\nclass_name SatoriLogger\n\nenum LOG_LEVEL {NONE, ERROR, WARNING, INFO, VERBOSE, DEBUG}\n\nvar _level = LO"
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori/utils/SatoriSerializer.gd",
    "chars": 4584,
    "preview": "extends RefCounted\nclass_name SatoriSerializer\n\nstatic func serialize(p_obj : Object) -> Dictionary:\n\tvar out = {}\n\tvar "
  },
  {
    "path": "addons/com.heroiclabs.nakama/Satori.gd",
    "chars": 1194,
    "preview": "@tool\nextends Node\n\n# The default host address of the server.\nconst DEFAULT_HOST : String = \"127.0.0.1\"\n\n# The default p"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaAPI.gd",
    "chars": 212718,
    "preview": "### Code generated by codegen/main.go. DO NOT EDIT. ###\n\nextends RefCounted\nclass_name NakamaAPI\n\n# A single user-role p"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd",
    "chars": 31697,
    "preview": "extends NakamaAsyncResult\n\nclass_name NakamaRTAPI\n\n# A chat channel on the server.\nclass Channel extends NakamaAsyncResu"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd",
    "chars": 17932,
    "preview": "extends RefCounted\nclass_name NakamaRTMessage\n\n# Send a channel join message to the server.\nclass ChannelJoin:\n\n\tconst _"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaSession.gd",
    "chars": 3517,
    "preview": "extends NakamaAsyncResult\nclass_name NakamaSession\n\nvar _created : bool = false\nvar created : bool:\n\tset(v):\n\t\tpass\n\tget"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaStorageObjectId.gd",
    "chars": 736,
    "preview": "extends RefCounted\nclass_name NakamaStorageObjectId\n\n# The collection which stores the object.\nvar collection : String\n\n"
  },
  {
    "path": "addons/com.heroiclabs.nakama/api/NakamaWriteStorageObject.gd",
    "chars": 736,
    "preview": "extends RefCounted\nclass_name NakamaWriteStorageObject\n\nvar collection : String\nvar key : String\nvar permission_read : i"
  },
  {
    "path": "addons/com.heroiclabs.nakama/client/NakamaClient.gd",
    "chars": 53873,
    "preview": "extends RefCounted\n\n# A client for the API in Nakama server.\nclass_name NakamaClient\n\nconst ChannelType = NakamaRTMessag"
  },
  {
    "path": "addons/com.heroiclabs.nakama/client/NakamaHTTPAdapter.gd",
    "chars": 6244,
    "preview": "@tool\nextends Node\n\n# An adapter which implements the HTTP protocol.\nclass_name NakamaHTTPAdapter\n\n# The logger to use w"
  },
  {
    "path": "addons/com.heroiclabs.nakama/dotnet-utils/GodotHttpAdapter.cs",
    "chars": 4193,
    "preview": "// Copyright 2022 The Nakama Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
  },
  {
    "path": "addons/com.heroiclabs.nakama/dotnet-utils/GodotLogger.cs",
    "chars": 2551,
    "preview": "// Copyright 2022 The Nakama Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
  },
  {
    "path": "addons/com.heroiclabs.nakama/dotnet-utils/GodotWebSocketAdapter.cs",
    "chars": 7108,
    "preview": "// Copyright 2022 The Nakama Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may no"
  },
  {
    "path": "addons/com.heroiclabs.nakama/socket/NakamaSocket.gd",
    "chars": 25319,
    "preview": "extends RefCounted\n\n# A socket to interact with Nakama server.\nclass_name NakamaSocket\n\nconst ChannelType = NakamaRTMess"
  },
  {
    "path": "addons/com.heroiclabs.nakama/socket/NakamaSocketAdapter.gd",
    "chars": 2436,
    "preview": "@tool\nextends Node\n\n# An adapter which implements a socket with a protocol supported by Nakama.\nclass_name NakamaSocketA"
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaAsyncResult.gd",
    "chars": 791,
    "preview": "extends RefCounted\nclass_name NakamaAsyncResult\n\nvar exception : NakamaException:\n\tset(v):\n\t\tpass\n\tget:\n\t\treturn get_exc"
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaException.gd",
    "chars": 925,
    "preview": "extends RefCounted\n\n# An exception generated during a request.\n# Usually contains at least an error message.\nclass_name "
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaLogger.gd",
    "chars": 825,
    "preview": "extends RefCounted\nclass_name NakamaLogger\n\nenum LOG_LEVEL {NONE, ERROR, WARNING, INFO, VERBOSE, DEBUG}\n\nvar _level = LO"
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaMultiplayerBridge.gd",
    "chars": 10999,
    "preview": "extends RefCounted\nclass_name NakamaMultiplayerBridge\n\nenum MatchState {\n\tDISCONNECTED,\n\tJOINING,\n\tCONNECTED,\n\tSOCKET_CL"
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaMultiplayerPeer.gd",
    "chars": 2332,
    "preview": "extends MultiplayerPeerExtension\nclass_name NakamaMultiplayerPeer\n\nconst MAX_PACKET_SIZE := 1 << 24\n\nvar _self_id := 0\nv"
  },
  {
    "path": "addons/com.heroiclabs.nakama/utils/NakamaSerializer.gd",
    "chars": 4418,
    "preview": "extends RefCounted\nclass_name NakamaSerializer\n\nstatic func serialize(p_obj : Object) -> Dictionary:\n\tvar out = {}\n\tvar "
  },
  {
    "path": "addons/nakama-webrtc/LICENSE.txt",
    "chars": 1062,
    "preview": "Copyright (c) 2019-2021 David Snopek\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof th"
  },
  {
    "path": "addons/nakama-webrtc/OnlineMatch.gd",
    "chars": 20371,
    "preview": "extends Node\n\n# For developers to set from the outside, for example:\n#   OnlineMatch.max_players = 8\n#   OnlineMatch.cli"
  },
  {
    "path": "assets/LICENSE.md",
    "chars": 17691,
    "preview": "## creative commons\n\n# Attribution-NonCommercial 4.0 International\n\nCreative Commons Corporation (“Creative Commons”) is"
  },
  {
    "path": "assets/README.md",
    "chars": 218,
    "preview": "This folder contains assets.\n\nNote that only the .import files are checked into git. The actual .png, .mp3 files are sto"
  },
  {
    "path": "assets/creeps/README.md",
    "chars": 261,
    "preview": "Assets in this folder CANNOT be shared.\nShare placeholders instead. Generate placeholders with generate_censored_assets."
  },
  {
    "path": "assets/creeps/orc/air/fly_E.png.import",
    "chars": 771,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b5se2dom7rt6d\"\npath=\"res://.godot/imported/fly_E.png-d"
  },
  {
    "path": "assets/creeps/orc/air/fly_N.png.import",
    "chars": 771,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dg22ncv2bbgpl\"\npath=\"res://.godot/imported/fly_N.png-d"
  },
  {
    "path": "assets/creeps/orc/air/fly_NE.png.import",
    "chars": 773,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://lhbh8ncpikea\"\npath=\"res://.godot/imported/fly_NE.png-8"
  },
  {
    "path": "assets/creeps/orc/air/fly_NW.png.import",
    "chars": 773,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://m74fw3s6vh5h\"\npath=\"res://.godot/imported/fly_NW.png-7"
  },
  {
    "path": "assets/creeps/orc/air/fly_S.png.import",
    "chars": 771,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ctrob5r1weymb\"\npath=\"res://.godot/imported/fly_S.png-4"
  },
  {
    "path": "assets/creeps/orc/air/fly_SE.png.import",
    "chars": 774,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dejolx201xt4l\"\npath=\"res://.godot/imported/fly_SE.png-"
  },
  {
    "path": "assets/creeps/orc/air/fly_SW.png.import",
    "chars": 774,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://beysr35mknwqu\"\npath=\"res://.godot/imported/fly_SW.png-"
  },
  {
    "path": "assets/creeps/orc/air/fly_W.png.import",
    "chars": 771,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ddhb3w0ho041v\"\npath=\"res://.godot/imported/fly_W.png-2"
  },
  {
    "path": "assets/creeps/orc/air/metadata.csv",
    "chars": 437,
    "preview": "name,row_count,col_count,sprite_count,offset_x,offset_y\nfly_E,7,4,25,0.01201923098415,0.05306122452021\nfly_N,7,4,25,0.01"
  },
  {
    "path": "assets/creeps/orc/air/metadata.csv.import",
    "chars": 25,
    "preview": "[remap]\n\nimporter=\"keep\"\n"
  },
  {
    "path": "assets/creeps/orc/boss/death_E.png.import",
    "chars": 778,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b1s341ilp1g0f\"\npath=\"res://.godot/imported/death_E.png"
  },
  {
    "path": "assets/creeps/orc/boss/death_N.png.import",
    "chars": 777,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://kyq50l132wm1\"\npath=\"res://.godot/imported/death_N.png-"
  },
  {
    "path": "assets/creeps/orc/boss/death_S.png.import",
    "chars": 778,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cmytlwkuq6i8q\"\npath=\"res://.godot/imported/death_S.png"
  },
  {
    "path": "assets/creeps/orc/boss/death_W.png.import",
    "chars": 777,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://pulp58p3vflw\"\npath=\"res://.godot/imported/death_W.png-"
  },
  {
    "path": "assets/creeps/orc/boss/metadata.csv",
    "chars": 460,
    "preview": "name,row_count,col_count,sprite_count,offset_x,offset_y\ndeath_E,7,4,28,0.0024509804789,0.0247104242444\ndeath_N,7,4,28,0."
  },
  {
    "path": "assets/creeps/orc/boss/metadata.csv.import",
    "chars": 25,
    "preview": "[remap]\n\nimporter=\"keep\"\n"
  },
  {
    "path": "assets/creeps/orc/boss/slow_run_E.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c4mbacosga5se\"\npath=\"res://.godot/imported/slow_run_E."
  },
  {
    "path": "assets/creeps/orc/boss/slow_run_N.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dcrmib66n1i1k\"\npath=\"res://.godot/imported/slow_run_N."
  },
  {
    "path": "assets/creeps/orc/boss/slow_run_S.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://be8at5qd2xtfm\"\npath=\"res://.godot/imported/slow_run_S."
  },
  {
    "path": "assets/creeps/orc/boss/slow_run_W.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bf8mfmg7jkmv7\"\npath=\"res://.godot/imported/slow_run_W."
  },
  {
    "path": "assets/creeps/orc/champion/death_E.png.import",
    "chars": 781,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://hdtvoqf7jppc\"\npath=\"res://.godot/imported/death_E.png-"
  },
  {
    "path": "assets/creeps/orc/champion/death_N.png.import",
    "chars": 782,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bt0fnps8to5c5\"\npath=\"res://.godot/imported/death_N.png"
  },
  {
    "path": "assets/creeps/orc/champion/death_S.png.import",
    "chars": 782,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bn3cfvfeop2ni\"\npath=\"res://.godot/imported/death_S.png"
  },
  {
    "path": "assets/creeps/orc/champion/death_W.png.import",
    "chars": 782,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dvwut2d2wdqo3\"\npath=\"res://.godot/imported/death_W.png"
  },
  {
    "path": "assets/creeps/orc/champion/metadata.csv",
    "chars": 462,
    "preview": "name,row_count,col_count,sprite_count,offset_x,offset_y\ndeath_E,7,4,28,0.01123595517129,0.02873563207686\ndeath_N,7,4,28,"
  },
  {
    "path": "assets/creeps/orc/champion/metadata.csv.import",
    "chars": 25,
    "preview": "[remap]\n\nimporter=\"keep\"\n"
  },
  {
    "path": "assets/creeps/orc/champion/slow_run_E.png.import",
    "chars": 791,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ch7gt4062eyrj\"\npath=\"res://.godot/imported/slow_run_E."
  },
  {
    "path": "assets/creeps/orc/champion/slow_run_N.png.import",
    "chars": 791,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dxvx01jjvjcye\"\npath=\"res://.godot/imported/slow_run_N."
  },
  {
    "path": "assets/creeps/orc/champion/slow_run_S.png.import",
    "chars": 791,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://d4cer5fkla46y\"\npath=\"res://.godot/imported/slow_run_S."
  },
  {
    "path": "assets/creeps/orc/champion/slow_run_W.png.import",
    "chars": 791,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bvaegexu3foek\"\npath=\"res://.godot/imported/slow_run_W."
  },
  {
    "path": "assets/creeps/orc/mass/death_E.png.import",
    "chars": 778,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c031gwyl83vsh\"\npath=\"res://.godot/imported/death_E.png"
  },
  {
    "path": "assets/creeps/orc/mass/death_N.png.import",
    "chars": 778,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://byqwfls7534ta\"\npath=\"res://.godot/imported/death_N.png"
  },
  {
    "path": "assets/creeps/orc/mass/death_S.png.import",
    "chars": 778,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dc3ghqhhglmqi\"\npath=\"res://.godot/imported/death_S.png"
  },
  {
    "path": "assets/creeps/orc/mass/death_W.png.import",
    "chars": 777,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://e7syh2jbikvl\"\npath=\"res://.godot/imported/death_W.png-"
  },
  {
    "path": "assets/creeps/orc/mass/metadata.csv",
    "chars": 463,
    "preview": "name,row_count,col_count,sprite_count,offset_x,offset_y\ndeath_E,7,4,28,0.00811688322574,0.03686635941267\ndeath_N,7,4,28,"
  },
  {
    "path": "assets/creeps/orc/mass/metadata.csv.import",
    "chars": 25,
    "preview": "[remap]\n\nimporter=\"keep\"\n"
  },
  {
    "path": "assets/creeps/orc/mass/slow_run_E.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bd5vg4oke4m70\"\npath=\"res://.godot/imported/slow_run_E."
  },
  {
    "path": "assets/creeps/orc/mass/slow_run_N.png.import",
    "chars": 786,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://jmweiopkc2gm\"\npath=\"res://.godot/imported/slow_run_N.p"
  },
  {
    "path": "assets/creeps/orc/mass/slow_run_S.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://beanme0cwvawx\"\npath=\"res://.godot/imported/slow_run_S."
  },
  {
    "path": "assets/creeps/orc/mass/slow_run_W.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c2kjqefq762mo\"\npath=\"res://.godot/imported/slow_run_W."
  },
  {
    "path": "assets/creeps/orc/normal/death_E.png.import",
    "chars": 779,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://3fls0dd5msho\"\npath=\"res://.godot/imported/death_E.png-"
  },
  {
    "path": "assets/creeps/orc/normal/death_N.png.import",
    "chars": 780,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ceyrhdt7hrlvb\"\npath=\"res://.godot/imported/death_N.png"
  },
  {
    "path": "assets/creeps/orc/normal/death_S.png.import",
    "chars": 780,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ca3nyf1hqvlca\"\npath=\"res://.godot/imported/death_S.png"
  },
  {
    "path": "assets/creeps/orc/normal/death_W.png.import",
    "chars": 779,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://nh8ulueomejj\"\npath=\"res://.godot/imported/death_W.png-"
  },
  {
    "path": "assets/creeps/orc/normal/metadata.csv",
    "chars": 442,
    "preview": "name,row_count,col_count,sprite_count,offset_x,offset_y\ndeath_E,7,4,28,0.0441176481545,0.03763900697231\ndeath_N,7,4,28,0"
  },
  {
    "path": "assets/creeps/orc/normal/metadata.csv.import",
    "chars": 25,
    "preview": "[remap]\n\nimporter=\"keep\"\n"
  },
  {
    "path": "assets/creeps/orc/normal/slow_run_E.png.import",
    "chars": 789,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dby3igs0d3hvn\"\npath=\"res://.godot/imported/slow_run_E."
  },
  {
    "path": "assets/creeps/orc/normal/slow_run_N.png.import",
    "chars": 789,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bns6kclfij3yy\"\npath=\"res://.godot/imported/slow_run_N."
  },
  {
    "path": "assets/creeps/orc/normal/slow_run_S.png.import",
    "chars": 789,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bshgy2yv32i6a\"\npath=\"res://.godot/imported/slow_run_S."
  },
  {
    "path": "assets/creeps/orc/normal/slow_run_W.png.import",
    "chars": 788,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://5hpj51wwf21h\"\npath=\"res://.godot/imported/slow_run_W.p"
  },
  {
    "path": "assets/effects/arrow.png.import",
    "chars": 764,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://djotx5jk18gc0\"\npath=\"res://.godot/imported/arrow.png-9"
  },
  {
    "path": "assets/effects/bdragon/README.md",
    "chars": 232,
    "preview": "Assets in this folder CANNOT be shared.\nShare placeholders instead. Generate placeholders with generate_censored_assets."
  },
  {
    "path": "assets/effects/bdragon/ancient_protector_missile_293.png.import",
    "chars": 844,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dwdvvm6bwoxfw\"\npath=\"res://.godot/imported/ancient_pro"
  },
  {
    "path": "assets/effects/bdragon/animated_dead_target_102.png.import",
    "chars": 829,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c4t5ody7wg6wa\"\npath=\"res://.godot/imported/animated_de"
  },
  {
    "path": "assets/effects/bdragon/apply_potion_537.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bvcsmcf7c2lf8\"\npath=\"res://.godot/imported/apply_potio"
  },
  {
    "path": "assets/effects/bdragon/arcane_tower_attack_024.png.import",
    "chars": 826,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c4xwqnjdc1ipo\"\npath=\"res://.godot/imported/arcane_towe"
  },
  {
    "path": "assets/effects/bdragon/avatar_caster_10.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bpanfd3kpr8y7\"\npath=\"res://.godot/imported/avatar_cast"
  },
  {
    "path": "assets/effects/bdragon/banshee_missile_487.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c1q82fl7tji4e\"\npath=\"res://.godot/imported/banshee_mis"
  },
  {
    "path": "assets/effects/bdragon/blink_target_720.png.import",
    "chars": 804,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://l77fhcp00n6l\"\npath=\"res://.godot/imported/blink_target"
  },
  {
    "path": "assets/effects/bdragon/blood_splatter_376.png.import",
    "chars": 810,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cueu6nx32scn\"\npath=\"res://.godot/imported/blood_splatt"
  },
  {
    "path": "assets/effects/bdragon/build_tower_648.png.import",
    "chars": 802,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dng7ptld4y130\"\npath=\"res://.godot/imported/build_tower"
  },
  {
    "path": "assets/effects/bdragon/charm_target_703.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c75jmqs4u7hnv\"\npath=\"res://.godot/imported/charm_targe"
  },
  {
    "path": "assets/effects/bdragon/cloud_of_fog_382.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dhm5njivfgxpo\"\npath=\"res://.godot/imported/cloud_of_fo"
  },
  {
    "path": "assets/effects/bdragon/cloud_of_fog_small_428.png.import",
    "chars": 822,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://m4w03jglmnu1\"\npath=\"res://.godot/imported/cloud_of_fog"
  },
  {
    "path": "assets/effects/bdragon/cripple_target_198.png.import",
    "chars": 811,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://crdvk0hy3x3px\"\npath=\"res://.godot/imported/cripple_tar"
  },
  {
    "path": "assets/effects/bdragon/crushing_wave_damage_584.png.import",
    "chars": 829,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bxvpwc34g1fgw\"\npath=\"res://.godot/imported/crushing_wa"
  },
  {
    "path": "assets/effects/bdragon/crypt_fiend_eggsack_528.png.import",
    "chars": 826,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cvu38ecsot0h2\"\npath=\"res://.godot/imported/crypt_fiend"
  },
  {
    "path": "assets/effects/bdragon/cyclone_target_269.png.import",
    "chars": 811,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://d4e4pstgsefwc\"\npath=\"res://.godot/imported/cyclone_tar"
  },
  {
    "path": "assets/effects/bdragon/death_and_decay_71.png.import",
    "chars": 810,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c8w3beqtm72u\"\npath=\"res://.godot/imported/death_and_de"
  },
  {
    "path": "assets/effects/bdragon/death_coil_special_728.png.import",
    "chars": 823,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cbmu8xdosr3xw\"\npath=\"res://.godot/imported/death_coil_"
  },
  {
    "path": "assets/effects/bdragon/devour_509.png.import",
    "chars": 787,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dqligfo47vxn1\"\npath=\"res://.godot/imported/devour_509."
  },
  {
    "path": "assets/effects/bdragon/dispel_magic_target_456.png.import",
    "chars": 825,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://e2i8sa520qes\"\npath=\"res://.godot/imported/dispel_magic"
  },
  {
    "path": "assets/effects/bdragon/doom_death_451.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b7j12e3p73bqd\"\npath=\"res://.godot/imported/doom_death_"
  },
  {
    "path": "assets/effects/bdragon/faerie_dragon_missile_482.png.import",
    "chars": 832,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cuavhpswhvx4s\"\npath=\"res://.godot/imported/faerie_drag"
  },
  {
    "path": "assets/effects/bdragon/firelord_death_explode_77.png.import",
    "chars": 832,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bcgbhwc4vii7u\"\npath=\"res://.godot/imported/firelord_de"
  },
  {
    "path": "assets/effects/bdragon/flame_strike_embers_702.png.import",
    "chars": 826,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ddtif7hi5hsjr\"\npath=\"res://.godot/imported/flame_strik"
  },
  {
    "path": "assets/effects/bdragon/flower_aura_655.png.import",
    "chars": 802,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c78vkmjgqto8v\"\npath=\"res://.godot/imported/flower_aura"
  },
  {
    "path": "assets/effects/bdragon/frag_boom_spawn_426.png.import",
    "chars": 813,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://yvx6sbavyr4p\"\npath=\"res://.godot/imported/frag_boom_sp"
  },
  {
    "path": "assets/effects/bdragon/freezing_breath_519.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c22lkk5uieshi\"\npath=\"res://.godot/imported/freezing_br"
  },
  {
    "path": "assets/effects/bdragon/frost_armor_damage_474.png.import",
    "chars": 822,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ijncv7mjaq1q\"\npath=\"res://.godot/imported/frost_armor_"
  },
  {
    "path": "assets/effects/bdragon/frost_bolt_missile_063.png.import",
    "chars": 823,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cvxaisa1jliqu\"\npath=\"res://.godot/imported/frost_bolt_"
  },
  {
    "path": "assets/effects/bdragon/glaive_746.png.import",
    "chars": 786,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://204ebjk0432r\"\npath=\"res://.godot/imported/glaive_746.p"
  },
  {
    "path": "assets/effects/bdragon/gold_credit_673.png.import",
    "chars": 802,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://du2y31j6qbb5m\"\npath=\"res://.godot/imported/gold_credit"
  },
  {
    "path": "assets/effects/bdragon/gold_credit_88.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bg6jx8tkf0t6l\"\npath=\"res://.godot/imported/gold_credit"
  },
  {
    "path": "assets/effects/bdragon/healing_wave_target_453.png.import",
    "chars": 826,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c56ujjaxdg1my\"\npath=\"res://.godot/imported/healing_wav"
  },
  {
    "path": "assets/effects/bdragon/holy_bolt_241.png.import",
    "chars": 796,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bfnbtlckgbnfs\"\npath=\"res://.godot/imported/holy_bolt_2"
  },
  {
    "path": "assets/effects/bdragon/immolation_damage_541.png.import",
    "chars": 819,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://hyqt8yi512yh\"\npath=\"res://.godot/imported/immolation_d"
  },
  {
    "path": "assets/effects/bdragon/impale_hit_target_529.png.import",
    "chars": 819,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://tnlbuwsjjav0\"\npath=\"res://.godot/imported/impale_hit_t"
  },
  {
    "path": "assets/effects/bdragon/impale_target_dust_025.png.import",
    "chars": 823,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://brfqvsks7awtk\"\npath=\"res://.godot/imported/impale_targ"
  },
  {
    "path": "assets/effects/bdragon/incinerate_76.png.import",
    "chars": 796,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cujsekapgggit\"\npath=\"res://.godot/imported/incinerate_"
  },
  {
    "path": "assets/effects/bdragon/keeper_grove_missile_297.png.import",
    "chars": 829,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ch2peil7lqosf\"\npath=\"res://.godot/imported/keeper_grov"
  },
  {
    "path": "assets/effects/bdragon/level_up_455.png.import",
    "chars": 792,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://wspy8ha1qyck\"\npath=\"res://.godot/imported/level_up_455"
  },
  {
    "path": "assets/effects/bdragon/mana_burn_target_388.png.import",
    "chars": 817,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cgakg4s2ct3ru\"\npath=\"res://.godot/imported/mana_burn_t"
  },
  {
    "path": "assets/effects/bdragon/mana_shield_026.png.import",
    "chars": 802,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b01ug8hkohe4a\"\npath=\"res://.godot/imported/mana_shield"
  },
  {
    "path": "assets/effects/bdragon/mass_teleport_caster_335.png.import",
    "chars": 828,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ewm7nac57wox\"\npath=\"res://.godot/imported/mass_telepor"
  },
  {
    "path": "assets/effects/bdragon/mass_teleport_target_315.png.import",
    "chars": 829,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://biy8bqpp0e7kj\"\npath=\"res://.godot/imported/mass_telepo"
  },
  {
    "path": "assets/effects/bdragon/mirror_image_caster_711.png.import",
    "chars": 826,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cdt55t8kxtqiq\"\npath=\"res://.godot/imported/mirror_imag"
  },
  {
    "path": "assets/effects/bdragon/moonwell_target_584.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cxngu4anhtvk6\"\npath=\"res://.godot/imported/moonwell_ta"
  },
  {
    "path": "assets/effects/bdragon/ne_cancel_death_672.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bryrhw6t0k26o\"\npath=\"res://.godot/imported/ne_cancel_d"
  },
  {
    "path": "assets/effects/bdragon/ne_death_612.png.import",
    "chars": 793,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dbjenjgmw6cgt\"\npath=\"res://.godot/imported/ne_death_61"
  },
  {
    "path": "assets/effects/bdragon/placeholder_481.png.import",
    "chars": 801,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://8aycp6wxnpve\"\npath=\"res://.godot/imported/placeholder_"
  },
  {
    "path": "assets/effects/bdragon/polymorph_target_735.png.import",
    "chars": 817,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dcfs2k3q3dixg\"\npath=\"res://.godot/imported/polymorph_t"
  },
  {
    "path": "assets/effects/bdragon/projectile_explosion_299.png.import",
    "chars": 829,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cyyax4tkjt7au\"\npath=\"res://.godot/imported/projectile_"
  },
  {
    "path": "assets/effects/bdragon/purge_buff_target_195.png.import",
    "chars": 820,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dsvu05xjwic5g\"\npath=\"res://.godot/imported/purge_buff_"
  },
  {
    "path": "assets/effects/bdragon/quillspray_747.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cknypfqkfkgiq\"\npath=\"res://.godot/imported/quillspray_"
  },
  {
    "path": "assets/effects/bdragon/raise_skeleton_624.png.import",
    "chars": 811,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dfwypnwsg3p3u\"\npath=\"res://.godot/imported/raise_skele"
  },
  {
    "path": "assets/effects/bdragon/replenish_mana_334.png.import",
    "chars": 811,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cwembk4judxy3\"\npath=\"res://.godot/imported/replenish_m"
  },
  {
    "path": "assets/effects/bdragon/revive_human_623.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c7ufux57uh5ua\"\npath=\"res://.godot/imported/revive_huma"
  },
  {
    "path": "assets/effects/bdragon/roar_506.png.import",
    "chars": 780,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://un4kd4n5xqem\"\npath=\"res://.godot/imported/roar_506.png"
  },
  {
    "path": "assets/effects/bdragon/roots_235.png.import",
    "chars": 784,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ddh33dc161220\"\npath=\"res://.godot/imported/roots_235.p"
  },
  {
    "path": "assets/effects/bdragon/shackle_439.png.import",
    "chars": 790,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cv8vncnltc5ta\"\npath=\"res://.godot/imported/shackle_439"
  },
  {
    "path": "assets/effects/bdragon/shockwave_missile_440.png.import",
    "chars": 820,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://btlx0a8g4015b\"\npath=\"res://.godot/imported/shockwave_m"
  },
  {
    "path": "assets/effects/bdragon/silence_area_611.png.import",
    "chars": 805,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cetfk6yto1khh\"\npath=\"res://.godot/imported/silence_are"
  },
  {
    "path": "assets/effects/bdragon/small_flame_spawn_240.png.import",
    "chars": 820,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://caisjfsu3fyap\"\npath=\"res://.godot/imported/small_flame"
  },
  {
    "path": "assets/effects/bdragon/spell_aiil_452.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dr841ukdn8762\"\npath=\"res://.godot/imported/spell_aiil_"
  },
  {
    "path": "assets/effects/bdragon/spell_ailb_723.png.import",
    "chars": 798,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://0152qy55d5hs\"\npath=\"res://.godot/imported/spell_ailb_7"
  },
  {
    "path": "assets/effects/bdragon/spell_aima_194.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://csiqjph81rdq8\"\npath=\"res://.godot/imported/spell_aima_"
  },
  {
    "path": "assets/effects/bdragon/spell_aire_174.png.import",
    "chars": 797,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ne67yotbsow\"\npath=\"res://.godot/imported/spell_aire_17"
  },
  {
    "path": "assets/effects/bdragon/spell_aiso_295.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://carq8d0wtr1pl\"\npath=\"res://.godot/imported/spell_aiso_"
  },
  {
    "path": "assets/effects/bdragon/spell_alim_136.png.import",
    "chars": 799,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cxr4c28mmw4nn\"\npath=\"res://.godot/imported/spell_alim_"
  },
  {
    "path": "assets/effects/bdragon/spell_breaker_target_613.png.import",
    "chars": 828,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://gtoj6o1w8tv0\"\npath=\"res://.godot/imported/spell_breake"
  },
  {
    "path": "assets/effects/bdragon/spirit_link_target_175.png.import",
    "chars": 822,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://terakoeeqruj\"\npath=\"res://.godot/imported/spirit_link_"
  },
  {
    "path": "assets/effects/bdragon/stampede_missile_death_63.png.import",
    "chars": 832,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bbmm2xf32v0tx\"\npath=\"res://.godot/imported/stampede_mi"
  },
  {
    "path": "assets/effects/bdragon/starfall_target_257.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b7swdbv14utxv\"\npath=\"res://.godot/imported/starfall_ta"
  },
  {
    "path": "assets/effects/bdragon/thunder_clap_466.png.import",
    "chars": 804,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://2dquk1ppfku0\"\npath=\"res://.godot/imported/thunder_clap"
  },
  {
    "path": "assets/effects/bdragon/undead_dissipate_633.png.import",
    "chars": 817,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://blekt36dlhmd2\"\npath=\"res://.godot/imported/undead_diss"
  },
  {
    "path": "assets/effects/bdragon/upgrade_tower_016.png.import",
    "chars": 808,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cpuu4w0gghqoe\"\npath=\"res://.godot/imported/upgrade_tow"
  },
  {
    "path": "assets/effects/bdragon/vampiric_aura_199.png.import",
    "chars": 807,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b2nm17eb4jt7\"\npath=\"res://.godot/imported/vampiric_aur"
  },
  {
    "path": "assets/effects/bdragon/voodoo_aura_182.png.import",
    "chars": 802,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cktvui85usgvp\"\npath=\"res://.godot/imported/voodoo_aura"
  },
  {
    "path": "assets/effects/bdragon/warstomp_caster_536.png.import",
    "chars": 814,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://di3fq4jkhoq4y\"\npath=\"res://.godot/imported/warstomp_ca"
  },
  {
    "path": "assets/effects/bdragon/wind_shear_559.png.import",
    "chars": 798,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://4vi0ba0hi12o\"\npath=\"res://.godot/imported/wind_shear_5"
  },
  {
    "path": "assets/effects/bdragon/wisp_explode_003.png.import",
    "chars": 804,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://pb01lu85dqby\"\npath=\"res://.godot/imported/wisp_explode"
  },
  {
    "path": "assets/effects/bdragon/ziggurat_frost_missile_325.png.import",
    "chars": 835,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bvvxqx0twqcdq\"\npath=\"res://.godot/imported/ziggurat_fr"
  },
  {
    "path": "assets/effects/bdragon/zombify_target_274.png.import",
    "chars": 811,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dtoev5csbiekv\"\npath=\"res://.godot/imported/zombify_tar"
  },
  {
    "path": "assets/effects/death_explode.png.import",
    "chars": 788,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://ctpc46l8ddp8n\"\npath=\"res://.godot/imported/death_explo"
  },
  {
    "path": "assets/effects/lightning_long.png.import",
    "chars": 791,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dyle0v7ow0gxp\"\npath=\"res://.godot/imported/lightning_l"
  },
  {
    "path": "assets/effects/stun.png.import",
    "chars": 761,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bmtjm6qhm3rop\"\npath=\"res://.godot/imported/stun.png-70"
  },
  {
    "path": "assets/fonts/Friz Quadrata Std Medium.otf.import",
    "chars": 835,
    "preview": "[remap]\n\nimporter=\"font_data_dynamic\"\ntype=\"FontFile\"\nuid=\"uid://d1pnwehsosppo\"\npath=\"res://.godot/imported/Friz Quadrat"
  },
  {
    "path": "assets/fonts/NotoSansSC-Medium.ttf.import",
    "chars": 731,
    "preview": "[remap]\n\nimporter=\"font_data_dynamic\"\ntype=\"FontFile\"\nuid=\"uid://b230565e8xtmg\"\npath=\"res://.godot/imported/NotoSansSC-M"
  },
  {
    "path": "assets/hud/bitmaps/circle_bitmap_100x100.png.import",
    "chars": 817,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://tuxggwvj4o35\"\npath=\"res://.godot/imported/circle_bitma"
  },
  {
    "path": "assets/hud/bitmaps/circle_bitmap_256x256.png.import",
    "chars": 816,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://cbw3opxuts8mj\"\npath=\"res://.godot/imported/circle_bitm"
  },
  {
    "path": "assets/hud/checkbox.png.import",
    "chars": 769,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bxfq60uwqny4m\"\npath=\"res://.godot/imported/checkbox.pn"
  },
  {
    "path": "assets/hud/circle_bitmap_256x256.png.import",
    "chars": 808,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dsbsuq1mmtbwf\"\npath=\"res://.godot/imported/circle_bitm"
  },
  {
    "path": "assets/hud/darkness_face.png.import",
    "chars": 784,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b3s3mtb8efipi\"\npath=\"res://.godot/imported/darkness_fa"
  },
  {
    "path": "assets/hud/element_progress_circle.png.import",
    "chars": 815,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://b36lpf5pdifac\"\npath=\"res://.godot/imported/element_pro"
  },
  {
    "path": "assets/hud/horadric_cube.png.import",
    "chars": 783,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://h5ppp14fvtrd\"\npath=\"res://.godot/imported/horadric_cub"
  },
  {
    "path": "assets/hud/hud_atlas.png.import",
    "chars": 773,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dl22jvey8l5fo\"\npath=\"res://.godot/imported/hud_atlas.p"
  },
  {
    "path": "assets/hud/misc2.png.import",
    "chars": 760,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://bf7g834206kwo\"\npath=\"res://.godot/imported/misc2.png-8"
  },
  {
    "path": "assets/hud/misc3.png.import",
    "chars": 759,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://60qc7jcvckhh\"\npath=\"res://.godot/imported/misc3.png-6f"
  },
  {
    "path": "assets/hud/misc3_s.png.import",
    "chars": 768,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dyixmgwifdsin\"\npath=\"res://.godot/imported/misc3_s.png"
  },
  {
    "path": "assets/hud/misc4.png.import",
    "chars": 760,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dfuxtb0pn0imr\"\npath=\"res://.godot/imported/misc4.png-3"
  },
  {
    "path": "assets/hud/tranquility_face.png.import",
    "chars": 792,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://mglwvt681k5r\"\npath=\"res://.godot/imported/tranquility_"
  },
  {
    "path": "assets/icons/amulets.png.import",
    "chars": 768,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c4f2vpcxem3iv\"\npath=\"res://.godot/imported/amulets.png"
  },
  {
    "path": "assets/icons/animals.png.import",
    "chars": 768,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dqw2twgahvt7e\"\npath=\"res://.godot/imported/animals.png"
  },
  {
    "path": "assets/icons/armor.png.import",
    "chars": 761,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://jy45uwdi1vwj\"\npath=\"res://.godot/imported/armor.png-cd"
  },
  {
    "path": "assets/icons/blunt_weapons.png.import",
    "chars": 786,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://dxmouedtoclok\"\npath=\"res://.godot/imported/blunt_weapo"
  }
]

// ... and 2846 more files (download for full content)

About this extraction

This page contains the full source code of the Praytic/youtd2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 3046 files (5.3 MB), approximately 1.6M tokens, and a symbol index with 23 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!