diff --git a/Assets/_Project/Levels/LevelAuthoring.cs b/Assets/_Project/Levels/LevelAuthoring.cs
index 5bd8ba5..792cc5d 100644
--- a/Assets/_Project/Levels/LevelAuthoring.cs
+++ b/Assets/_Project/Levels/LevelAuthoring.cs
@@ -51,6 +51,16 @@ namespace TD.Levels
[Tooltip("Optional author/credit text. Empty triggers a soft warning at bake time.")]
public string author = "";
+ [Header("Rules")]
+ [Tooltip("OwnerOnly: players can only build inside their own PlayerZoneVolume — the classic " +
+ "one-maze-each layout.\n\n" +
+ "Shared: any player can build on any Buildable tile, so the whole map is one " +
+ "cooperative maze. Zones still define territory for leak attribution, camera " +
+ "start, builder spawn and minimap tinting — only the build restriction lifts.\n\n" +
+ "Towers always belong to whoever paid for them; sell and upgrade stay owner-gated " +
+ "under both modes.")]
+ public BuildAccess buildAccess = BuildAccess.OwnerOnly;
+
// -------------------------------------------------------------------
// Gizmo visibility toggles. Each volume type reads its own toggle to decide whether to
// draw always-on or only-when-selected.
diff --git a/Assets/_Project/Levels/LevelData.cs b/Assets/_Project/Levels/LevelData.cs
index faba95b..288b056 100644
--- a/Assets/_Project/Levels/LevelData.cs
+++ b/Assets/_Project/Levels/LevelData.cs
@@ -63,6 +63,17 @@ namespace TD.Levels
public BakeOutcome LastBakeOutcome;
public int LastBakeWarningCount;
+ // -------------------------------------------------------------------
+ // Match rules.
+ // -------------------------------------------------------------------
+
+ [Header("Rules")]
+ [Tooltip("Whether players are restricted to building in their own zone (OwnerOnly) or can " +
+ "build anywhere on the map's buildable area (Shared). Affects placement permission " +
+ "only — OwnerGrid still drives leak attribution, camera start, builder spawn and " +
+ "minimap tinting under both modes.")]
+ public BuildAccess BuildAccess;
+
// -------------------------------------------------------------------
// Grid metadata.
// -------------------------------------------------------------------
diff --git a/Assets/_Project/Prefabs/MatchCore.meta b/Assets/_Project/Prefabs/MatchCore.meta
new file mode 100644
index 0000000..3efebf9
--- /dev/null
+++ b/Assets/_Project/Prefabs/MatchCore.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: cf34e1b2cedcd9a4fa7f938f8f0bf3c2
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab
new file mode 100644
index 0000000..e8eb442
--- /dev/null
+++ b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab
@@ -0,0 +1,483 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1348868032911320215
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2098889495380348335}
+ - component: {fileID: 8734966915826773517}
+ - component: {fileID: 6131651964009722688}
+ m_Layer: 0
+ m_Name: TowerPlacementManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2098889495380348335
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1348868032911320215}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8734966915826773517
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1348868032911320215}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 3734927306
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &6131651964009722688
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1348868032911320215}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d369496ba7887b844b1c220b524a507d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementManager
+ ShowTopMostFoldoutHeaderGroup: 1
+ requestsPerFrame: 3
+ towerDefinitions:
+ - {fileID: 0}
+ - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2}
+ - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2}
+ - {fileID: 11400000, guid: 86d4c3ab00d4c654eb4c255280ee5701, type: 2}
+ - {fileID: 11400000, guid: 04219895bbea4fb9a94fd62fef35bf2a, type: 2}
+ - {fileID: 11400000, guid: e3f1a9c2b5d84e76a0c3f1e8d27b4905, type: 2}
+ startingDeck:
+ - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2}
+ - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2}
+--- !u!1 &5626802001211498962
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 3648445760525794609}
+ - component: {fileID: 4563436515829454556}
+ - component: {fileID: 8936124320851695101}
+ m_Layer: 0
+ m_Name: WaveManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &3648445760525794609
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5626802001211498962}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4563436515829454556
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5626802001211498962}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 3957247190
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &8936124320851695101
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5626802001211498962}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 81d8e215d8419404ea4d959196cd9cc3, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.WaveManager
+ ShowTopMostFoldoutHeaderGroup: 1
+ startingLives: 40
+ draftTimeSeconds: 30
+ voteTimeSeconds: 25
+ goldConfig: {fileID: 11400000, guid: d5e01c919f14a1e4888ad494a159241b, type: 2}
+ enemyScalingConfig: {fileID: 11400000, guid: ae9fde0b564e20440ac2e20861fa1ca6, type: 2}
+--- !u!1 &6226139915412633039
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8547990667945757531}
+ - component: {fileID: 4703036714451320211}
+ - component: {fileID: 2895480021437825520}
+ m_Layer: 0
+ m_Name: MatchState
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &8547990667945757531
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6226139915412633039}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &4703036714451320211
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6226139915412633039}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 1618207171
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &2895480021437825520
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6226139915412633039}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a34585be59d49e94b811d96be51c5088, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.MatchState
+ ShowTopMostFoldoutHeaderGroup: 1
+--- !u!1 &8213601217886697539
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1789974153803072425}
+ - component: {fileID: 5759999417597858157}
+ - component: {fileID: 8805989965283647635}
+ m_Layer: 0
+ m_Name: RunState
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1789974153803072425
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8213601217886697539}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &5759999417597858157
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8213601217886697539}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 3660389945
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &8805989965283647635
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8213601217886697539}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a293cf6dca91dd2478c9f4e799cf9e0d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Waves.RunState
+ ShowTopMostFoldoutHeaderGroup: 1
+ runDefinition: {fileID: 11400000, guid: 1bb81a966192c344d94cce2628c1832b, type: 2}
+--- !u!1 &8429081419068942390
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5251454257324784754}
+ m_Layer: 0
+ m_Name: MatchNetwork
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &5251454257324784754
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8429081419068942390}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2182889149551291466}
+ - {fileID: 8547990667945757531}
+ - {fileID: 1789974153803072425}
+ - {fileID: 2098889495380348335}
+ - {fileID: 3648445760525794609}
+ - {fileID: 2625678984567986094}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &9094815948999422851
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2182889149551291466}
+ - component: {fileID: 8307773927879075679}
+ - component: {fileID: 3604854611554599773}
+ m_Layer: 0
+ m_Name: ChatService
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2182889149551291466
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9094815948999422851}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8307773927879075679
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9094815948999422851}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 1681065116
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &3604854611554599773
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9094815948999422851}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 816890bb20c416b419e38d3d4b91ffca, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.ChatService
+ ShowTopMostFoldoutHeaderGroup: 1
+--- !u!1 &9150709944481815107
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2625678984567986094}
+ - component: {fileID: 1287556557852043940}
+ - component: {fileID: 4386956365137913543}
+ m_Layer: 0
+ m_Name: WaveVote
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2625678984567986094
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9150709944481815107}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5251454257324784754}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1287556557852043940
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9150709944481815107}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 3520766009
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &4386956365137913543
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 9150709944481815107}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a18321dc2d138034fbdb5f705f19f893, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.WaveVote
+ ShowTopMostFoldoutHeaderGroup: 1
+ optionsPerVote: 3
diff --git a/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta
new file mode 100644
index 0000000..707a454
--- /dev/null
+++ b/Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 7116de1968afffb4990ee24f709612fb
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab
new file mode 100644
index 0000000..edfdc8b
--- /dev/null
+++ b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab
@@ -0,0 +1,921 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &216401704418653358
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2369632775351055227}
+ - component: {fileID: 5469845921758518005}
+ - component: {fileID: 1431563384465486267}
+ m_Layer: 0
+ m_Name: HUD
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2369632775351055227
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 216401704418653358}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3833381251955063088}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &5469845921758518005
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 216401704418653358}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
+ m_PanelSettings: {fileID: 11400000, guid: 6aa0af71585acea4db4995c3931dc946, type: 2}
+ m_ParentUI: {fileID: 0}
+ sourceAsset: {fileID: 9197481963319205126, guid: eba711c1def2b194584102ceb5517c48, type: 3}
+ m_SortingOrder: 0
+ m_Position: 0
+ m_WorldSpaceSizeMode: 1
+ m_WorldSpaceWidth: 1920
+ m_WorldSpaceHeight: 1080
+ m_PivotReferenceSize: 0
+ m_Pivot: 0
+ m_WorldSpaceCollider: {fileID: 0}
+--- !u!114 &1431563384465486267
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 216401704418653358}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1c69cd177f09f0c419288f73b49df886, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.UI.HUDController
+ placementController: {fileID: 7706260725108150093}
+ paintController: {fileID: 559798155559411408}
+ placementManager: {fileID: 0}
+ cameraController: {fileID: 5042310339586537117}
+ rejectionMessageDuration: 2.5
+ menuButtonIcon: {fileID: 0}
+ chatMaxHeight: 280
+ chatMaxMessages: 2147483647
+ chatSystemColor: {r: 1, g: 0.7, b: 0.2, a: 1}
+ chatPlayerColor: {r: 0.92, g: 0.92, b: 0.92, a: 1}
+--- !u!1 &1445952844252628864
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 3833381251955063088}
+ - component: {fileID: 6850685008819507485}
+ - component: {fileID: 3524271020287320838}
+ - component: {fileID: 6600478213912852129}
+ - component: {fileID: 191939159250915621}
+ - component: {fileID: 7706260725108150093}
+ - component: {fileID: 559798155559411408}
+ - component: {fileID: 1988948222073846279}
+ - component: {fileID: 2077830364583566817}
+ - component: {fileID: 8797807118405570736}
+ - component: {fileID: 3273128039403554245}
+ - component: {fileID: 1661838386639436151}
+ - component: {fileID: 8864891455444378183}
+ - component: {fileID: 7594921744928559756}
+ - component: {fileID: 1678455881203478607}
+ - component: {fileID: 8637796564860235120}
+ - component: {fileID: 4396752746502665908}
+ - component: {fileID: 9162204174128098398}
+ - component: {fileID: 4044629536480845444}
+ - component: {fileID: 1951038390230828916}
+ m_Layer: 0
+ m_Name: MatchServices
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &3833381251955063088
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2369632775351055227}
+ - {fileID: 2545698982756849348}
+ - {fileID: 9174177271844320236}
+ - {fileID: 7648787753941018277}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &6850685008819507485
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a303b690faebb0e4e930d1714afa424e, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.LevelLoader
+ level: {fileID: 0}
+ buildablePlaneLayerName: BuildablePlane
+ drawGridBounds: 1
+ drawWalkability: 1
+ drawBuildablePlane: 1
+ drawOwnerBorders: 1
+--- !u!114 &3524271020287320838
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: de7d013503af0f74c950f215f8dae1c0, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.PathfindingService
+ recomputeBudgetMs: 1.5
+--- !u!114 &6600478213912852129
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: dc307e7e94967894584e8e6050fc38cf, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.SelectionState
+--- !u!114 &191939159250915621
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: e28d10549c8d2ac4585eded3ad8d2198, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.SelectionVisualizer
+ selectionRingPrefab: {fileID: 8648063358813763958, guid: 74757e379bac0e444aabab5e388e17c6, type: 3}
+ yOffset: 0.02
+ projectionLayerMask:
+ serializedVersion: 2
+ m_Bits: 960
+--- !u!114 &7706260725108150093
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 124253f2cbc2d9f46befb6e1763cd6b9, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementController
+ settings: {fileID: 11400000, guid: 18f99b4b94d13eb429d4dfb9b0b37b4b, type: 2}
+ buildablePlaneLayerMask:
+ serializedVersion: 2
+ m_Bits: 64
+ raycastMaxDistance: 500
+--- !u!114 &559798155559411408
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6b81770471b644b3aa0e58d4a108dddd, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPaintController
+ raycastMaxDistance: 500
+ cursorSize: 28
+--- !u!114 &1988948222073846279
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: cc99a2b3d3e8d8178a74e1d68a34553c, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderSpellCastController
+ groundLayerMask:
+ serializedVersion: 2
+ m_Bits: 128
+ raycastMaxDistance: 500
+ aimDecal: {fileID: 0}
+ pointReticleDiameter: 1.5
+ projectionDepth: 50
+--- !u!114 &2077830364583566817
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a31401869def6d64c87e645f1da1aa2a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.UI.FloatingTextSpawner
+ prefab: {fileID: 4844901775730304629, guid: e5002bdc91043d24994f0b1cb578de56, type: 3}
+ goldColor: {r: 1, g: 0.84, b: 0.2, a: 1}
+ livesColor: {r: 0.95, g: 0.25, b: 0.25, a: 1}
+ verticalOffset: 2
+ positionJitter: 0.4
+ verticalJitter: 0.2
+--- !u!114 &8797807118405570736
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: e2708c6bac8136f45b48c899d3d40630, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.VFX.SellEffectSpawner
+ coinBurstPrefab: {fileID: 2313150535691989867, guid: 31f8d8c320b42c54d886d610fb13a1e7, type: 3}
+ sellSound:
+ clip: {fileID: 8300000, guid: 778b3d5981f4c3045a475794435f43cc, type: 3}
+ volume: 1
+ minPitch: 0.95
+ maxPitch: 1.05
+ verticalOffset: 0.75
+--- !u!114 &3273128039403554245
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 9ec21c01769ef58d1ac26ba89668eeaa, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Audio.AudioManager
+ categories:
+ - category: 0
+ maxVoices: 6
+ volume: 0.5
+ - category: 1
+ maxVoices: 4
+ volume: 0.5
+ - category: 2
+ maxVoices: 4
+ volume: 0.5
+--- !u!82 &1661838386639436151
+AudioSource:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ serializedVersion: 4
+ OutputAudioMixerGroup: {fileID: 0}
+ m_audioClip: {fileID: 0}
+ m_Resource: {fileID: 0}
+ m_PlayOnAwake: 1
+ m_Volume: 1
+ m_Pitch: 1
+ Loop: 0
+ Mute: 0
+ Spatialize: 0
+ SpatializePostEffects: 0
+ Priority: 128
+ DopplerLevel: 1
+ MinDistance: 1
+ MaxDistance: 500
+ Pan2D: 0
+ rolloffMode: 0
+ BypassEffects: 0
+ BypassListenerEffects: 0
+ BypassReverbZones: 0
+ rolloffCustomCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 1
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ - serializedVersion: 3
+ time: 1
+ value: 0
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ panLevelCustomCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ spreadCustomCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ reverbZoneMixCustomCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 1
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+--- !u!114 &8864891455444378183
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 292ad37b9e4d1d7c28e59cf4dc1e99fa, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Audio.MusicPlayer
+ clip: {fileID: 8300000, guid: d4626563ad3c90179b247207e7b9f0be, type: 3}
+ volume: 0.632
+--- !u!114 &7594921744928559756
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6226c6e672c5b358a9cdc2a1bee47daf, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderEffects.BuilderEffectPool
+ effects:
+ - {fileID: 11400000, guid: 419fac0976a3e0a20827beff81826161, type: 2}
+--- !u!114 &1678455881203478607
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 36a7be1b3824682b8a183fbcf8564652, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuilderSpells.BuilderSpellPool
+ spells:
+ - {fileID: 11400000, guid: 051c48f416e5366b59d49b0e062333ac, type: 2}
+ - {fileID: 11400000, guid: d893f46b037536b4ba91307e184cecfe, type: 2}
+ - {fileID: 11400000, guid: 364edf6abc3c31e33b53d0a01142b8ab, type: 2}
+--- !u!114 &8637796564860235120
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4409eb25a8be555de8dc3a73d4ed95db, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyAbilities.EnemyAbilityPool
+ abilities:
+ - {fileID: 11400000, guid: 0305468bc8f912d429a8b20bf23f947c, type: 2}
+ - {fileID: 11400000, guid: 030f10c9a264e544ea3e0f4fdb4171bd, type: 2}
+ - {fileID: 11400000, guid: cb2ec6bb70f57d0429b99b7cd4c7db73, type: 2}
+ - {fileID: 11400000, guid: a18691a20d75f17479a83b3e171759e7, type: 2}
+ - {fileID: 11400000, guid: c64c7121b0456bb4a873acec9e0abf91, type: 2}
+--- !u!114 &4396752746502665908
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: c4d98a01d9b9a7b438a6f91b0b7f498f, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.EnemyUpgradePool
+ options:
+ - {fileID: 11400000, guid: eef28ca7b8844504e9d75ff903a3bb61, type: 2}
+ - {fileID: 11400000, guid: 46e2a6a59c0a3034f9fa44681d9ba422, type: 2}
+ - {fileID: 11400000, guid: 80fb851b702ff304183cb6e89c4aa245, type: 2}
+ - {fileID: 11400000, guid: a67aa3644d2ad4847a47040f53fea26f, type: 2}
+ - {fileID: 11400000, guid: 37d761966a349ba4cb4141f913224d5c, type: 2}
+ - {fileID: 11400000, guid: f6bfb033a15b6d0419587b80a8286bd1, type: 2}
+--- !u!114 &9162204174128098398
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5a7e1f3c9d2b4867a1c0e4f8b3d6792a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Draft.DraftPool
+ options:
+ - {fileID: 11400000, guid: 6b1d3f8a2c5e4097b8a1d0c3e6f9b240, type: 2}
+ - {fileID: 11400000, guid: f4a2b8d1c6e93f05a7b2d4c8e1f6a930, type: 2}
+ - {fileID: 11400000, guid: 0b9f4905752751f44b9959b84b620266, type: 2}
+ - {fileID: 11400000, guid: 65ff25c1c8a89f7df8e88f71968c1c98, type: 2}
+ - {fileID: 11400000, guid: 5f390de69ba43b2a6a0d89cf09580320, type: 2}
+ - {fileID: 11400000, guid: 29b35841f7e5db454903798cb5d83434, type: 2}
+ - {fileID: 11400000, guid: d180030b68a9a5e1da497bf6f83451d4, type: 2}
+--- !u!114 &4044629536480845444
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 9d3a7c5e1b8f42606a2d4e9f1c7b3850, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Draft.DraftService
+ optionsPerDraft: 3
+ rerollCost: 50
+--- !u!114 &1951038390230828916
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1445952844252628864}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 468de2ce61e73ce4595ba4792874b076, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Dev.DevWaveControls
+ hotkey: 94
+ grantTowerHotkey: 101
+ skipToBossHotkey: 100
+--- !u!1 &2434986514412567376
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 9174177271844320236}
+ - component: {fileID: 5042310339586537117}
+ m_Layer: 0
+ m_Name: CameraRig
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &9174177271844320236
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2434986514412567376}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 7042465335914098461}
+ m_Father: {fileID: 3833381251955063088}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &5042310339586537117
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2434986514412567376}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1e670a36689801e428873c5712ea3679, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.CameraController
+ cameraChild: {fileID: 5566698628747533439}
+ basePanSpeed: 12
+ edgePanMarginPixels: 16
+ edgePanEnabled: 1
+ minDollyDistance: 5
+ maxDollyDistance: 50
+ startDollyDistance: 25
+ zoomSpeed: 3
+ cursorAnchoredZoom: 1
+ minPitchDegrees: 30
+ maxPitchDegrees: 75
+ startPitchDegrees: 50
+ pitchSpeed: 4
+--- !u!1 &2936049029850371745
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7042465335914098461}
+ - component: {fileID: 5566698628747533439}
+ - component: {fileID: 9062733689301865828}
+ - component: {fileID: 7984992879034746998}
+ m_Layer: 0
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &7042465335914098461
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2936049029850371745}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 9174177271844320236}
+ m_LocalEulerAnglesHint: {x: 45, y: -90, z: 0}
+--- !u!20 &5566698628747533439
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2936049029850371745}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 1
+ m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_Iso: 200
+ m_ShutterSpeed: 0.005
+ m_Aperture: 16
+ m_FocusDistance: 10
+ m_FocalLength: 50
+ m_BladeCount: 5
+ m_Curvature: {x: 2, y: 11}
+ m_BarrelClipping: 0.25
+ m_Anamorphism: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: 0.3
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 0
+ orthographic size: 5
+ m_Depth: -1
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingPath: -1
+ m_TargetTexture: {fileID: 0}
+ m_TargetDisplay: 0
+ m_TargetEye: 3
+ m_HDR: 1
+ m_AllowMSAA: 1
+ m_AllowDynamicResolution: 0
+ m_ForceIntoRT: 0
+ m_OcclusionCulling: 1
+ m_StereoConvergence: 10
+ m_StereoSeparation: 0.022
+--- !u!81 &9062733689301865828
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2936049029850371745}
+ m_Enabled: 1
+--- !u!114 &7984992879034746998
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2936049029850371745}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_RenderShadows: 1
+ m_RequiresDepthTextureOption: 2
+ m_RequiresOpaqueTextureOption: 2
+ m_CameraType: 0
+ m_Cameras: []
+ m_RendererIndex: -1
+ m_VolumeLayerMask:
+ serializedVersion: 2
+ m_Bits: 1
+ m_VolumeTrigger: {fileID: 0}
+ m_VolumeFrameworkUpdateModeOption: 2
+ m_RenderPostProcessing: 1
+ m_Antialiasing: 0
+ m_AntialiasingQuality: 2
+ m_StopNaN: 0
+ m_Dithering: 0
+ m_ClearDepth: 1
+ m_AllowXRRendering: 1
+ m_AllowHDROutput: 1
+ m_UseScreenCoordOverride: 0
+ m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
+ m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
+ m_RequiresDepthTexture: 0
+ m_RequiresColorTexture: 0
+ m_TaaSettings:
+ m_Quality: 3
+ m_FrameInfluence: 0.1
+ m_JitterScale: 1
+ m_MipBias: 0
+ m_VarianceClampScale: 0.9
+ m_ContrastAdaptiveSharpening: 0
+ m_Version: 2
+--- !u!1 &3584612494616813666
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2545698982756849348}
+ - component: {fileID: 9037991996416952042}
+ - component: {fileID: 6848311735055501230}
+ m_Layer: 0
+ m_Name: DebugConsole
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2545698982756849348
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3584612494616813666}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: -52.51635, y: 0, z: -27.6311}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3833381251955063088}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &9037991996416952042
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3584612494616813666}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
+ m_PanelSettings: {fileID: 11400000, guid: 6aa0af71585acea4db4995c3931dc946, type: 2}
+ m_ParentUI: {fileID: 0}
+ sourceAsset: {fileID: 0}
+ m_SortingOrder: 1
+ m_Position: 0
+ m_WorldSpaceSizeMode: 1
+ m_WorldSpaceWidth: 1920
+ m_WorldSpaceHeight: 1080
+ m_PivotReferenceSize: 0
+ m_Pivot: 0
+ m_WorldSpaceCollider: {fileID: 0}
+--- !u!114 &6848311735055501230
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3584612494616813666}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 7c6a808e8291552d0b64e36a210879c4, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Dev.DebugConsole
+ toggleKey: 4
+--- !u!1 &5697898299420166755
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7648787753941018277}
+ - component: {fileID: 4271007794402033964}
+ - component: {fileID: 1710569614611447900}
+ m_Layer: 0
+ m_Name: Directional Light
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &7648787753941018277
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5697898299420166755}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0.0000014901161, y: 0.9063078, z: -0.42261824, w: 0.00000295043}
+ m_LocalPosition: {x: -17, y: 3, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3833381251955063088}
+ m_LocalEulerAnglesHint: {x: 50, y: 180, z: 0}
+--- !u!108 &4271007794402033964
+Light:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5697898299420166755}
+ m_Enabled: 1
+ serializedVersion: 13
+ m_Type: 1
+ m_Color: {r: 0.8156863, g: 0.9098039, b: 1, a: 1}
+ m_Intensity: 0.65
+ m_Range: 10
+ m_SpotAngle: 30
+ m_InnerSpotAngle: 21.80208
+ m_CookieSize2D: {x: 10, y: 10}
+ m_Shadows:
+ m_Type: 2
+ m_Resolution: -1
+ m_CustomResolution: -1
+ m_Strength: 1
+ m_Bias: 0.05
+ m_NormalBias: 0.4
+ m_NearPlane: 0.2
+ m_CullingMatrixOverride:
+ e00: 1
+ e01: 0
+ e02: 0
+ e03: 0
+ e10: 0
+ e11: 1
+ e12: 0
+ e13: 0
+ e20: 0
+ e21: 0
+ e22: 1
+ e23: 0
+ e30: 0
+ e31: 0
+ e32: 0
+ e33: 1
+ m_UseCullingMatrixOverride: 0
+ m_Cookie: {fileID: 0}
+ m_DrawHalo: 0
+ m_Flare: {fileID: 0}
+ m_RenderMode: 0
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingLayerMask: 1
+ m_Lightmapping: 4
+ m_LightShadowCasterMode: 0
+ m_AreaSize: {x: 1, y: 1}
+ m_BounceIntensity: 1
+ m_ColorTemperature: 7191
+ m_UseColorTemperature: 1
+ m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+ m_UseBoundingSphereOverride: 0
+ m_UseViewFrustumForShadowCasterCull: 1
+ m_ForceVisible: 0
+ m_ShapeRadius: 0
+ m_ShadowAngle: 0
+ m_LightUnit: 1
+ m_LuxAtDistance: 1
+ m_EnableSpotReflector: 1
+--- !u!114 &1710569614611447900
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 5697898299420166755}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_UsePipelineSettings: 1
+ m_AdditionalLightsShadowResolutionTier: 2
+ m_CustomShadowLayers: 0
+ m_LightCookieSize: {x: 1, y: 1}
+ m_LightCookieOffset: {x: 0, y: 0}
+ m_SoftShadowQuality: 1
+ m_RenderingLayersMask:
+ serializedVersion: 0
+ m_Bits: 1
+ m_ShadowRenderingLayersMask:
+ serializedVersion: 0
+ m_Bits: 1
+ m_Version: 4
+ m_LightLayerMask: 1
+ m_ShadowLayerMask: 1
+ m_RenderingLayers: 1
+ m_ShadowRenderingLayers: 1
diff --git a/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta
new file mode 100644
index 0000000..0ec6795
--- /dev/null
+++ b/Assets/_Project/Prefabs/MatchCore/MatchServices.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 13be8328f6275e14da787f25c94683ee
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Scenes/Levels/3Player.asset b/Assets/_Project/Scenes/Levels/3Player.asset
new file mode 100644
index 0000000..e991500
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player.asset
@@ -0,0 +1,327 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6d4e9c37b9205f3408a8225823f7a4da, type: 3}
+ m_Name: 3Player
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LevelData
+ MapName: 3Player
+ PlayerCount: 3
+ MapDescription: 3 Player new design map
+ Author: BigBoysFellowship
+ MapThumbnail: {fileID: 21300000, guid: 7e33bd8556d93f04eb4f5c38006a7880, type: 3}
+ ScenePath: Assets/_Project/Scenes/Levels/3Player.unity
+ AuthoringHash: bb69927c7e56c27f8073227f6af654d08b2b8a72ed8439ac4fb5392cb4132b67
+ LastBakeTimestamp: 2026-08-05T05:39:40.7353238Z
+ LastBakeOutcome: 1
+ LastBakeWarningCount: 3
+ BuildAccess: 1
+ GridOriginTile: {x: 0, y: 0}
+ GridSize: {x: 100, y: 100}
+ PlacementGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101020202020202020202020101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101000000000002020202020101010101010101010101010101010101010101010101010101010101010101010101010101010102020202020202020202010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101020202020202020201010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020202020202020202020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ WalkabilityGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ OwnerGrid: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000002020202020202020202020202020202020202020202020202020202020202020202020202020202000000000000000000000202020202020202020202020202020202020202020202020202020202020202020202020202020200000000000000000000020202020202020202020202020202020202020202020202020202020202020202020202020202020000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303000000000000000000000303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ MapAreaGrid: 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
+ PlayerZones:
+ - Owner: 1
+ Spawners:
+ - SpawnerIdInZone: 0
+ TilePosition: {x: 50, y: 3}
+ TileArea:
+ - {x: 45, y: 0}
+ - {x: 46, y: 0}
+ - {x: 47, y: 0}
+ - {x: 48, y: 0}
+ - {x: 49, y: 0}
+ - {x: 50, y: 0}
+ - {x: 51, y: 0}
+ - {x: 52, y: 0}
+ - {x: 53, y: 0}
+ - {x: 54, y: 0}
+ - {x: 45, y: 1}
+ - {x: 46, y: 1}
+ - {x: 47, y: 1}
+ - {x: 48, y: 1}
+ - {x: 49, y: 1}
+ - {x: 50, y: 1}
+ - {x: 51, y: 1}
+ - {x: 52, y: 1}
+ - {x: 53, y: 1}
+ - {x: 54, y: 1}
+ - {x: 45, y: 2}
+ - {x: 46, y: 2}
+ - {x: 47, y: 2}
+ - {x: 48, y: 2}
+ - {x: 49, y: 2}
+ - {x: 50, y: 2}
+ - {x: 51, y: 2}
+ - {x: 52, y: 2}
+ - {x: 53, y: 2}
+ - {x: 54, y: 2}
+ - {x: 45, y: 3}
+ - {x: 46, y: 3}
+ - {x: 47, y: 3}
+ - {x: 48, y: 3}
+ - {x: 49, y: 3}
+ - {x: 50, y: 3}
+ - {x: 51, y: 3}
+ - {x: 52, y: 3}
+ - {x: 53, y: 3}
+ - {x: 54, y: 3}
+ - {x: 45, y: 4}
+ - {x: 46, y: 4}
+ - {x: 47, y: 4}
+ - {x: 48, y: 4}
+ - {x: 49, y: 4}
+ - {x: 50, y: 4}
+ - {x: 51, y: 4}
+ - {x: 52, y: 4}
+ - {x: 53, y: 4}
+ - {x: 54, y: 4}
+ Facing: 0
+ LeakExits:
+ - Target: 2
+ TileArea:
+ - {x: 36, y: 44}
+ - {x: 37, y: 44}
+ - {x: 38, y: 44}
+ - {x: 39, y: 44}
+ - {x: 40, y: 44}
+ - {x: 41, y: 44}
+ - {x: 42, y: 44}
+ - {x: 43, y: 44}
+ NormalizedWeight: 1
+ - Owner: 2
+ Spawners:
+ - SpawnerIdInZone: 0
+ TilePosition: {x: 2, y: 50}
+ TileArea:
+ - {x: 0, y: 45}
+ - {x: 1, y: 45}
+ - {x: 2, y: 45}
+ - {x: 3, y: 45}
+ - {x: 4, y: 45}
+ - {x: 0, y: 46}
+ - {x: 1, y: 46}
+ - {x: 2, y: 46}
+ - {x: 3, y: 46}
+ - {x: 4, y: 46}
+ - {x: 0, y: 47}
+ - {x: 1, y: 47}
+ - {x: 2, y: 47}
+ - {x: 3, y: 47}
+ - {x: 4, y: 47}
+ - {x: 0, y: 48}
+ - {x: 1, y: 48}
+ - {x: 2, y: 48}
+ - {x: 3, y: 48}
+ - {x: 4, y: 48}
+ - {x: 0, y: 49}
+ - {x: 1, y: 49}
+ - {x: 2, y: 49}
+ - {x: 3, y: 49}
+ - {x: 4, y: 49}
+ - {x: 0, y: 50}
+ - {x: 1, y: 50}
+ - {x: 2, y: 50}
+ - {x: 3, y: 50}
+ - {x: 4, y: 50}
+ - {x: 0, y: 51}
+ - {x: 1, y: 51}
+ - {x: 2, y: 51}
+ - {x: 3, y: 51}
+ - {x: 4, y: 51}
+ - {x: 0, y: 52}
+ - {x: 1, y: 52}
+ - {x: 2, y: 52}
+ - {x: 3, y: 52}
+ - {x: 4, y: 52}
+ - {x: 0, y: 53}
+ - {x: 1, y: 53}
+ - {x: 2, y: 53}
+ - {x: 3, y: 53}
+ - {x: 4, y: 53}
+ - {x: 0, y: 54}
+ - {x: 1, y: 54}
+ - {x: 2, y: 54}
+ - {x: 3, y: 54}
+ - {x: 4, y: 54}
+ Facing: 0
+ LeakExits:
+ - Target: 3
+ TileArea:
+ - {x: 36, y: 55}
+ - {x: 37, y: 55}
+ - {x: 38, y: 55}
+ - {x: 39, y: 55}
+ - {x: 40, y: 55}
+ - {x: 41, y: 55}
+ - {x: 42, y: 55}
+ - {x: 43, y: 55}
+ NormalizedWeight: 1
+ - Owner: 3
+ Spawners:
+ - SpawnerIdInZone: 0
+ TilePosition: {x: 50, y: 97}
+ TileArea:
+ - {x: 45, y: 95}
+ - {x: 46, y: 95}
+ - {x: 47, y: 95}
+ - {x: 48, y: 95}
+ - {x: 49, y: 95}
+ - {x: 50, y: 95}
+ - {x: 51, y: 95}
+ - {x: 52, y: 95}
+ - {x: 53, y: 95}
+ - {x: 54, y: 95}
+ - {x: 45, y: 96}
+ - {x: 46, y: 96}
+ - {x: 47, y: 96}
+ - {x: 48, y: 96}
+ - {x: 49, y: 96}
+ - {x: 50, y: 96}
+ - {x: 51, y: 96}
+ - {x: 52, y: 96}
+ - {x: 53, y: 96}
+ - {x: 54, y: 96}
+ - {x: 45, y: 97}
+ - {x: 46, y: 97}
+ - {x: 47, y: 97}
+ - {x: 48, y: 97}
+ - {x: 49, y: 97}
+ - {x: 50, y: 97}
+ - {x: 51, y: 97}
+ - {x: 52, y: 97}
+ - {x: 53, y: 97}
+ - {x: 54, y: 97}
+ - {x: 45, y: 98}
+ - {x: 46, y: 98}
+ - {x: 47, y: 98}
+ - {x: 48, y: 98}
+ - {x: 49, y: 98}
+ - {x: 50, y: 98}
+ - {x: 51, y: 98}
+ - {x: 52, y: 98}
+ - {x: 53, y: 98}
+ - {x: 54, y: 98}
+ - {x: 45, y: 99}
+ - {x: 46, y: 99}
+ - {x: 47, y: 99}
+ - {x: 48, y: 99}
+ - {x: 49, y: 99}
+ - {x: 50, y: 99}
+ - {x: 51, y: 99}
+ - {x: 52, y: 99}
+ - {x: 53, y: 99}
+ - {x: 54, y: 99}
+ Facing: 0
+ LeakExits: []
+ Goals:
+ - TileArea:
+ - {x: 45, y: 45}
+ - {x: 46, y: 45}
+ - {x: 47, y: 45}
+ - {x: 48, y: 45}
+ - {x: 49, y: 45}
+ - {x: 50, y: 45}
+ - {x: 51, y: 45}
+ - {x: 52, y: 45}
+ - {x: 53, y: 45}
+ - {x: 54, y: 45}
+ - {x: 45, y: 46}
+ - {x: 46, y: 46}
+ - {x: 47, y: 46}
+ - {x: 48, y: 46}
+ - {x: 49, y: 46}
+ - {x: 50, y: 46}
+ - {x: 51, y: 46}
+ - {x: 52, y: 46}
+ - {x: 53, y: 46}
+ - {x: 54, y: 46}
+ - {x: 45, y: 47}
+ - {x: 46, y: 47}
+ - {x: 47, y: 47}
+ - {x: 48, y: 47}
+ - {x: 49, y: 47}
+ - {x: 50, y: 47}
+ - {x: 51, y: 47}
+ - {x: 52, y: 47}
+ - {x: 53, y: 47}
+ - {x: 54, y: 47}
+ - {x: 45, y: 48}
+ - {x: 46, y: 48}
+ - {x: 47, y: 48}
+ - {x: 48, y: 48}
+ - {x: 49, y: 48}
+ - {x: 50, y: 48}
+ - {x: 51, y: 48}
+ - {x: 52, y: 48}
+ - {x: 53, y: 48}
+ - {x: 54, y: 48}
+ - {x: 45, y: 49}
+ - {x: 46, y: 49}
+ - {x: 47, y: 49}
+ - {x: 48, y: 49}
+ - {x: 49, y: 49}
+ - {x: 50, y: 49}
+ - {x: 51, y: 49}
+ - {x: 52, y: 49}
+ - {x: 53, y: 49}
+ - {x: 54, y: 49}
+ - {x: 45, y: 50}
+ - {x: 46, y: 50}
+ - {x: 47, y: 50}
+ - {x: 48, y: 50}
+ - {x: 49, y: 50}
+ - {x: 50, y: 50}
+ - {x: 51, y: 50}
+ - {x: 52, y: 50}
+ - {x: 53, y: 50}
+ - {x: 54, y: 50}
+ - {x: 45, y: 51}
+ - {x: 46, y: 51}
+ - {x: 47, y: 51}
+ - {x: 48, y: 51}
+ - {x: 49, y: 51}
+ - {x: 50, y: 51}
+ - {x: 51, y: 51}
+ - {x: 52, y: 51}
+ - {x: 53, y: 51}
+ - {x: 54, y: 51}
+ - {x: 45, y: 52}
+ - {x: 46, y: 52}
+ - {x: 47, y: 52}
+ - {x: 48, y: 52}
+ - {x: 49, y: 52}
+ - {x: 50, y: 52}
+ - {x: 51, y: 52}
+ - {x: 52, y: 52}
+ - {x: 53, y: 52}
+ - {x: 54, y: 52}
+ - {x: 45, y: 53}
+ - {x: 46, y: 53}
+ - {x: 47, y: 53}
+ - {x: 48, y: 53}
+ - {x: 49, y: 53}
+ - {x: 50, y: 53}
+ - {x: 51, y: 53}
+ - {x: 52, y: 53}
+ - {x: 53, y: 53}
+ - {x: 54, y: 53}
+ - {x: 45, y: 54}
+ - {x: 46, y: 54}
+ - {x: 47, y: 54}
+ - {x: 48, y: 54}
+ - {x: 49, y: 54}
+ - {x: 50, y: 54}
+ - {x: 51, y: 54}
+ - {x: 52, y: 54}
+ - {x: 53, y: 54}
+ - {x: 54, y: 54}
diff --git a/Assets/_Project/Scenes/Levels/3Player.asset.meta b/Assets/_Project/Scenes/Levels/3Player.asset.meta
new file mode 100644
index 0000000..165c532
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4ca1d0054e9d3744e8802817bf0b69e2
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Scenes/Levels/3Player.unity b/Assets/_Project/Scenes/Levels/3Player.unity
new file mode 100644
index 0000000..f76a371
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player.unity
@@ -0,0 +1,1682 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_OcclusionBakeSettings:
+ smallestOccluder: 5
+ smallestHole: 0.25
+ backfaceThreshold: 100
+ m_SceneGUID: 00000000000000000000000000000000
+ m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 10
+ m_Fog: 0
+ m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+ m_FogMode: 3
+ m_FogDensity: 0.01
+ m_LinearFogStart: 0
+ m_LinearFogEnd: 300
+ m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+ m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+ m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+ m_AmbientIntensity: 1
+ m_AmbientMode: 0
+ m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+ m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+ m_HaloStrength: 0.5
+ m_FlareStrength: 1
+ m_FlareFadeSpeed: 3
+ m_HaloTexture: {fileID: 0}
+ m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+ m_DefaultReflectionMode: 0
+ m_DefaultReflectionResolution: 128
+ m_ReflectionBounces: 1
+ m_ReflectionIntensity: 1
+ m_CustomReflection: {fileID: 0}
+ m_Sun: {fileID: 0}
+ m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 13
+ m_BakeOnSceneLoad: 0
+ m_GISettings:
+ serializedVersion: 2
+ m_BounceScale: 1
+ m_IndirectOutputScale: 1
+ m_AlbedoBoost: 1
+ m_EnvironmentLightingMode: 0
+ m_EnableBakedLightmaps: 1
+ m_EnableRealtimeLightmaps: 0
+ m_LightmapEditorSettings:
+ serializedVersion: 12
+ m_Resolution: 2
+ m_BakeResolution: 40
+ m_AtlasSize: 1024
+ m_AO: 0
+ m_AOMaxDistance: 1
+ m_CompAOExponent: 1
+ m_CompAOExponentDirect: 0
+ m_ExtractAmbientOcclusion: 0
+ m_Padding: 2
+ m_LightmapParameters: {fileID: 0}
+ m_LightmapsBakeMode: 1
+ m_TextureCompression: 1
+ m_ReflectionCompression: 2
+ m_MixedBakeMode: 2
+ m_BakeBackend: 2
+ m_PVRSampling: 1
+ m_PVRDirectSampleCount: 32
+ m_PVRSampleCount: 512
+ m_PVRBounces: 2
+ m_PVREnvironmentSampleCount: 256
+ m_PVREnvironmentReferencePointCount: 2048
+ m_PVRFilteringMode: 1
+ m_PVRDenoiserTypeDirect: 1
+ m_PVRDenoiserTypeIndirect: 1
+ m_PVRDenoiserTypeAO: 1
+ m_PVRFilterTypeDirect: 0
+ m_PVRFilterTypeIndirect: 0
+ m_PVRFilterTypeAO: 0
+ m_PVREnvironmentMIS: 1
+ m_PVRCulling: 1
+ m_PVRFilteringGaussRadiusDirect: 1
+ m_PVRFilteringGaussRadiusIndirect: 1
+ m_PVRFilteringGaussRadiusAO: 1
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_LightProbeSampleCountMultiplier: 4
+ m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+ m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+ serializedVersion: 2
+ m_ObjectHideFlags: 0
+ m_BuildSettings:
+ serializedVersion: 3
+ agentTypeID: 0
+ agentRadius: 0.5
+ agentHeight: 2
+ agentSlope: 45
+ agentClimb: 0.4
+ ledgeDropHeight: 0
+ maxJumpAcrossDistance: 0
+ minRegionArea: 2
+ manualCellSize: 0
+ cellSize: 0.16666667
+ manualTileSize: 0
+ tileSize: 256
+ buildHeightMesh: 0
+ maxJobWorkers: 0
+ preserveTilesOutsideBounds: 0
+ debug:
+ m_Flags: 0
+ m_NavMeshData: {fileID: 0}
+--- !u!1 &33702846
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 33702847}
+ - component: {fileID: 33702849}
+ - component: {fileID: 33702848}
+ m_Layer: 0
+ m_Name: Player2Zone
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &33702847
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 33702846}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 25, y: 0, z: 50}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1254053184}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &33702848
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 33702846}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume
+ owner: 2
+ placementValidity: 1
+--- !u!65 &33702849
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 33702846}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 40, y: 1, z: 10}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &134093951
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 134093952}
+ - component: {fileID: 134093954}
+ - component: {fileID: 134093953}
+ m_Layer: 0
+ m_Name: Player1Zone
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &134093952
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 134093951}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 25}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 928556819}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &134093953
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 134093951}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume
+ owner: 1
+ placementValidity: 1
+--- !u!65 &134093954
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 134093951}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 90, y: 1, z: 40}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &266460570
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 266460571}
+ - component: {fileID: 266460573}
+ - component: {fileID: 266460572}
+ m_Layer: 0
+ m_Name: Player2Leak
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &266460571
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 266460570}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 40.07, y: 0, z: 55.86}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1254053184}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &266460572
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 266460570}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d4da5d6673a12f546ac47563abc49d5a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LeakExitVolume
+ sourceZone: 2
+ target: 3
+ weight: 1
+ placementValidity: 0
+--- !u!65 &266460573
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 266460570}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 8, y: 1, z: 1}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &401715852
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 401715853}
+ - component: {fileID: 401715855}
+ - component: {fileID: 401715854}
+ m_Layer: 0
+ m_Name: Player1Spawn
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &401715853
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 401715852}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 3}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 928556819}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &401715854
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 401715852}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume
+ owner: 1
+ spawnerIdInZone: 0
+ spawnFacing: 0
+ placementValidity: 0
+--- !u!65 &401715855
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 401715852}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 10, y: 1, z: 5}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &459910557
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 459910558}
+ - component: {fileID: 459910560}
+ - component: {fileID: 459910559}
+ m_Layer: 0
+ m_Name: Player3Zone
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &459910558
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 459910557}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 74.8}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 795669283}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &459910559
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 459910557}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume
+ owner: 3
+ placementValidity: 1
+--- !u!65 &459910560
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 459910557}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 90, y: 1, z: 40}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &795669282
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 795669283}
+ m_Layer: 0
+ m_Name: Player 3
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &795669283
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 795669282}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 459910558}
+ - {fileID: 798920373}
+ m_Father: {fileID: 2019237589}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &798920372
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 798920373}
+ - component: {fileID: 798920375}
+ - component: {fileID: 798920374}
+ m_Layer: 0
+ m_Name: Player3Spawn
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &798920373
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 798920372}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 97.35}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 795669283}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &798920374
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 798920372}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume
+ owner: 3
+ spawnerIdInZone: 0
+ spawnFacing: 0
+ placementValidity: 0
+--- !u!65 &798920375
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 798920372}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 10, y: 1, z: 5}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &818973742
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 818973745}
+ - component: {fileID: 818973744}
+ - component: {fileID: 818973743}
+ m_Layer: 7
+ m_Name: Terrain
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 2147483647
+ m_IsActive: 1
+--- !u!154 &818973743
+TerrainCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 818973742}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 2
+ m_TerrainData: {fileID: 15600000, guid: ee9f119ba54c4b14d83c6818dc2f0ef8, type: 2}
+ m_EnableTreeColliders: 1
+--- !u!218 &818973744
+Terrain:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 818973742}
+ m_Enabled: 1
+ serializedVersion: 6
+ m_TerrainData: {fileID: 15600000, guid: ee9f119ba54c4b14d83c6818dc2f0ef8, type: 2}
+ m_TreeDistance: 5000
+ m_TreeBillboardDistance: 50
+ m_TreeCrossFadeLength: 5
+ m_TreeMaximumFullLODCount: 50
+ m_DetailObjectDistance: 80
+ m_DetailObjectDensity: 1
+ m_HeightmapPixelError: 5
+ m_SplatMapDistance: 1000
+ m_HeightmapMinimumLODSimplification: 0
+ m_HeightmapMaximumLOD: 0
+ m_ShadowCastingMode: 2
+ m_DrawHeightmap: 1
+ m_DrawInstanced: 0
+ m_DrawTreesAndFoliage: 1
+ m_StaticShadowCaster: 0
+ m_IgnoreQualitySettings: 0
+ m_ReflectionProbeUsage: 1
+ m_MaterialTemplate: {fileID: 2100000, guid: 594ea882c5a793440b60ff72d896021e, type: 2}
+ m_BakeLightProbesForTrees: 1
+ m_PreserveTreePrototypeLayers: 0
+ m_DeringLightProbesForTrees: 1
+ m_ReceiveGI: 1
+ m_ScaleInLightmap: 0.18285714
+ m_LightmapParameters: {fileID: 15203, guid: 0000000000000000f000000000000000, type: 0}
+ m_GroupingID: 0
+ m_RenderingLayerMask: 1
+ m_AllowAutoConnect: 1
+ m_EnableHeightmapRayTracing: 1
+ m_EnableTreesAndDetailsRayTracing: 0
+ m_TreeMotionVectorModeOverride: 3
+--- !u!4 &818973745
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 818973742}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: -20, y: -5, z: -20}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &928556818
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 928556819}
+ m_Layer: 0
+ m_Name: Player 1
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &928556819
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 928556818}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 134093952}
+ - {fileID: 401715853}
+ - {fileID: 1270045952}
+ m_Father: {fileID: 2019237589}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1085185471
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: 1445952844252628864, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_Name
+ value: _MatchServices
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 3833381251955063088, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6850685008819507485, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ propertyPath: level
+ value:
+ objectReference: {fileID: 11400000, guid: 4ca1d0054e9d3744e8802817bf0b69e2, type: 2}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+--- !u!1 &1254053183
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1254053184}
+ m_Layer: 0
+ m_Name: Player 2
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1254053184
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1254053183}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 33702847}
+ - {fileID: 1980551240}
+ - {fileID: 1422989821}
+ - {fileID: 266460571}
+ m_Father: {fileID: 2019237589}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1270045951
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1270045952}
+ - component: {fileID: 1270045954}
+ - component: {fileID: 1270045953}
+ m_Layer: 0
+ m_Name: Player1Leak
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1270045952
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1270045951}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 40.49, y: 0, z: 44.4}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 928556819}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1270045953
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1270045951}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d4da5d6673a12f546ac47563abc49d5a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LeakExitVolume
+ sourceZone: 1
+ target: 2
+ weight: 1
+ placementValidity: 0
+--- !u!65 &1270045954
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1270045951}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 8, y: 1, z: 1}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &1422989820
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1422989821}
+ - component: {fileID: 1422989823}
+ - component: {fileID: 1422989822}
+ m_Layer: 0
+ m_Name: Player2Spawn
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1422989821
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1422989820}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 2.72, y: 0, z: 50}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1254053184}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1422989822
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1422989820}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a756762f899008f45b2986bdcb11c819, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.SpawnerVolume
+ owner: 2
+ spawnerIdInZone: 0
+ spawnFacing: 0
+ placementValidity: 0
+--- !u!65 &1422989823
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1422989820}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 5, y: 1, z: 10}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &1725776290
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1725776291}
+ - component: {fileID: 1725776293}
+ - component: {fileID: 1725776292}
+ m_Layer: 0
+ m_Name: Goal
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1725776291
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1725776290}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 50}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 2019237589}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1725776292
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1725776290}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 755948f0244afea4da6ed2e4e3d27579, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.GoalVolume
+ placementValidity: 0
+--- !u!65 &1725776293
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1725776290}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 10, y: 1, z: 10}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &1980551239
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1980551240}
+ - component: {fileID: 1980551242}
+ - component: {fileID: 1980551241}
+ m_Layer: 0
+ m_Name: Player2Zone (1)
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1980551240
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1980551239}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 75.5, y: 0, z: 50}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1254053184}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1980551241
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1980551239}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5e8ab74b9038bd64782043bfc21f4cd7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.PlayerZoneVolume
+ owner: 2
+ placementValidity: 1
+--- !u!65 &1980551242
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1980551239}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 40, y: 1, z: 10}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &2019237587
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2019237589}
+ - component: {fileID: 2019237588}
+ m_Layer: 0
+ m_Name: _LevelAuthoring
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &2019237588
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2019237587}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 37de128911d7bbc4299ea87cdb520ed7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.LevelAuthoring
+ targetAsset: {fileID: 11400000, guid: 4ca1d0054e9d3744e8802817bf0b69e2, type: 2}
+ mapName: 3Player
+ playerCount: 3
+ expectedGoalCount: 1
+ mapDescription: 3 Player new design map
+ author: BigBoysFellowship
+ buildAccess: 1
+ alwaysShowPlayerZones: 1
+ alwaysShowSpawners: 1
+ alwaysShowLeakExits: 1
+ alwaysShowGoals: 1
+ alwaysShowMapArea: 1
+--- !u!4 &2019237589
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2019237587}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2082667048}
+ - {fileID: 1725776291}
+ - {fileID: 928556819}
+ - {fileID: 1254053184}
+ - {fileID: 795669283}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &2082667047
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2082667048}
+ - component: {fileID: 2082667050}
+ - component: {fileID: 2082667049}
+ m_Layer: 0
+ m_Name: MapArea
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2082667048
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2082667047}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 50, y: 0, z: 50}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 2019237589}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2082667049
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2082667047}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: bacb3662546735544bc6c56b5bf5830a, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Levels.MapAreaVolume
+--- !u!65 &2082667050
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2082667047}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Size: {x: 100, y: 1, z: 100}
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &3017635515177826
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8988393256734803841}
+ - component: {fileID: 8162852702969474156}
+ - component: {fileID: 3611798548410183501}
+ m_Layer: 0
+ m_Name: WaveManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &140582381973810141
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4602750115185197811}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 2907458687
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!4 &503343020638521026
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4244307270187979398}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 5789372923279415034}
+ - {fileID: 4088215286431904235}
+ - {fileID: 6254257571613030681}
+ - {fileID: 5997689683896399647}
+ - {fileID: 8988393256734803841}
+ - {fileID: 7668674954522045726}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1105731448975329059
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1764112936023248767}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 33007430
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!1 &1764112936023248767
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 4088215286431904235}
+ - component: {fileID: 1105731448975329059}
+ - component: {fileID: 7363980916811660096}
+ m_Layer: 0
+ m_Name: MatchState
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1946912819156519408
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6675731345053163047}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d369496ba7887b844b1c220b524a507d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerPlacementManager
+ ShowTopMostFoldoutHeaderGroup: 1
+ requestsPerFrame: 3
+ towerDefinitions:
+ - {fileID: 0}
+ - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2}
+ - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2}
+ - {fileID: 11400000, guid: 86d4c3ab00d4c654eb4c255280ee5701, type: 2}
+ - {fileID: 11400000, guid: 04219895bbea4fb9a94fd62fef35bf2a, type: 2}
+ - {fileID: 11400000, guid: e3f1a9c2b5d84e76a0c3f1e8d27b4905, type: 2}
+ startingDeck:
+ - {fileID: 11400000, guid: d5b2e8fa3c7e9b5f4a1d0c2e7f6b3a91, type: 2}
+ - {fileID: 11400000, guid: 0f693e29ca953e1439e10cb8f12e4b30, type: 2}
+--- !u!1 &3471031726177798451
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5789372923279415034}
+ - component: {fileID: 4420272328355700207}
+ - component: {fileID: 8942977016248842733}
+ m_Layer: 0
+ m_Name: ChatService
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!1 &3522105368117485811
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7668674954522045726}
+ - component: {fileID: 6900222455741435924}
+ - component: {fileID: 8285861969374059639}
+ m_Layer: 0
+ m_Name: WaveVote
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &3611798548410183501
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3017635515177826}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 81d8e215d8419404ea4d959196cd9cc3, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.WaveManager
+ ShowTopMostFoldoutHeaderGroup: 1
+ startingLives: 40
+ draftTimeSeconds: 30
+ voteTimeSeconds: 25
+ goldConfig: {fileID: 11400000, guid: d5e01c919f14a1e4888ad494a159241b, type: 2}
+ enemyScalingConfig: {fileID: 11400000, guid: ae9fde0b564e20440ac2e20861fa1ca6, type: 2}
+--- !u!114 &3758811521878612515
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4602750115185197811}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a293cf6dca91dd2478c9f4e799cf9e0d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.Waves.RunState
+ ShowTopMostFoldoutHeaderGroup: 1
+ runDefinition: {fileID: 11400000, guid: 1bb81a966192c344d94cce2628c1832b, type: 2}
+--- !u!114 &3973305430985036989
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6675731345053163047}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 2279944997
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!4 &4088215286431904235
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1764112936023248767}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &4244307270187979398
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 503343020638521026}
+ m_Layer: 0
+ m_Name: _MatchNetwork
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &4420272328355700207
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3471031726177798451}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 3614769064
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!1 &4602750115185197811
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 6254257571613030681}
+ - component: {fileID: 140582381973810141}
+ - component: {fileID: 3758811521878612515}
+ m_Layer: 0
+ m_Name: RunState
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &5789372923279415034
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3471031726177798451}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &5997689683896399647
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6675731345053163047}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &6254257571613030681
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4602750115185197811}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &6675731345053163047
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5997689683896399647}
+ - component: {fileID: 3973305430985036989}
+ - component: {fileID: 1946912819156519408}
+ m_Layer: 0
+ m_Name: TowerPlacementManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &6900222455741435924
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3522105368117485811}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 1445073833
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &7363980916811660096
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1764112936023248767}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a34585be59d49e94b811d96be51c5088, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.MatchState
+ ShowTopMostFoldoutHeaderGroup: 1
+--- !u!4 &7668674954522045726
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3522105368117485811}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 38.30481, y: 0.5, z: 155.93135}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8162852702969474156
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3017635515177826}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
+ GlobalObjectIdHash: 1797533733
+ InScenePlacedSourceGlobalObjectIdHash: 0
+ DeferredDespawnTick: 0
+ Ownership: 1
+ AlwaysReplicateAsRoot: 0
+ SynchronizeTransform: 1
+ ActiveSceneSynchronization: 0
+ SceneMigrationSynchronization: 0
+ SpawnWithObservers: 1
+ DontDestroyWithOwner: 0
+ AutoObjectParentSync: 1
+ SyncOwnerTransformWhenParented: 1
+ AllowOwnerToParent: 0
+--- !u!114 &8285861969374059639
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3522105368117485811}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a18321dc2d138034fbdb5f705f19f893, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.EnemyUpgrades.WaveVote
+ ShowTopMostFoldoutHeaderGroup: 1
+ optionsPerVote: 3
+--- !u!114 &8942977016248842733
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3471031726177798451}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 816890bb20c416b419e38d3d4b91ffca, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.ChatService
+ ShowTopMostFoldoutHeaderGroup: 1
+--- !u!4 &8988393256734803841
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3017635515177826}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 503343020638521026}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+ m_ObjectHideFlags: 0
+ m_Roots:
+ - {fileID: 1085185471}
+ - {fileID: 503343020638521026}
+ - {fileID: 2019237589}
+ - {fileID: 818973745}
diff --git a/Assets/_Project/Scenes/Levels/3Player.unity.meta b/Assets/_Project/Scenes/Levels/3Player.unity.meta
new file mode 100644
index 0000000..757486c
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 128de09101c3e3240b094d29d1eb9d22
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset b/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset
new file mode 100644
index 0000000..f27ca6b
Binary files /dev/null and b/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset differ
diff --git a/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset.meta b/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset.meta
new file mode 100644
index 0000000..8e8fbe8
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player_TerrainData.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ee9f119ba54c4b14d83c6818dc2f0ef8
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 15600000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png b/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png
new file mode 100644
index 0000000..58162bb
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e9721e2886a9b21f06f6f80010e37933fc07488fd6bb643dbe58e865503cb5b0
+size 868034
diff --git a/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png.meta b/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png.meta
new file mode 100644
index 0000000..d442f14
--- /dev/null
+++ b/Assets/_Project/Scenes/Levels/3Player_Thumbnail.png.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: 7e33bd8556d93f04eb4f5c38006a7880
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/_Project/Scenes/UI.meta b/Assets/_Project/Scenes/UI_Scenes.meta
similarity index 100%
rename from Assets/_Project/Scenes/UI.meta
rename to Assets/_Project/Scenes/UI_Scenes.meta
diff --git a/Assets/_Project/Scenes/UI/Lobby.unity b/Assets/_Project/Scenes/UI_Scenes/Lobby.unity
similarity index 100%
rename from Assets/_Project/Scenes/UI/Lobby.unity
rename to Assets/_Project/Scenes/UI_Scenes/Lobby.unity
diff --git a/Assets/_Project/Scenes/UI/Lobby.unity.meta b/Assets/_Project/Scenes/UI_Scenes/Lobby.unity.meta
similarity index 100%
rename from Assets/_Project/Scenes/UI/Lobby.unity.meta
rename to Assets/_Project/Scenes/UI_Scenes/Lobby.unity.meta
diff --git a/Assets/_Project/Scenes/UI/MainMenu.unity b/Assets/_Project/Scenes/UI_Scenes/MainMenu.unity
similarity index 99%
rename from Assets/_Project/Scenes/UI/MainMenu.unity
rename to Assets/_Project/Scenes/UI_Scenes/MainMenu.unity
index b6d1820..7ec922f 100644
--- a/Assets/_Project/Scenes/UI/MainMenu.unity
+++ b/Assets/_Project/Scenes/UI_Scenes/MainMenu.unity
@@ -638,6 +638,7 @@ MonoBehaviour:
maps:
- {fileID: 11400000, guid: e65cce766e92f604f85ab939cf374abd, type: 2}
- {fileID: 11400000, guid: 9cc56fbc3ae460a4b862f8510fdf5f09, type: 2}
+ - {fileID: 11400000, guid: 4ca1d0054e9d3744e8802817bf0b69e2, type: 2}
--- !u!4 &976902011
Transform:
m_ObjectHideFlags: 0
diff --git a/Assets/_Project/Scenes/UI/MainMenu.unity.meta b/Assets/_Project/Scenes/UI_Scenes/MainMenu.unity.meta
similarity index 100%
rename from Assets/_Project/Scenes/UI/MainMenu.unity.meta
rename to Assets/_Project/Scenes/UI_Scenes/MainMenu.unity.meta
diff --git a/Assets/_Project/Scripts/Core/Enums.cs b/Assets/_Project/Scripts/Core/Enums.cs
index 7d49400..43d7a92 100644
--- a/Assets/_Project/Scripts/Core/Enums.cs
+++ b/Assets/_Project/Scripts/Core/Enums.cs
@@ -203,6 +203,31 @@ namespace TD.Core
Restricted = 2,
}
+ ///
+ /// Whether a map restricts tower placement to each player's own zone, or lets everyone build
+ /// anywhere on the map's buildable area.
+ ///
+ ///
+ /// This governs placement PERMISSION only. Zone ownership keeps doing everything else it
+ /// does today under both modes — leak attribution, camera start position, builder spawn point,
+ /// minimap tinting. A shared-build map still has distinct player territories; they are simply
+ /// all buildable by everyone.
+ ///
+ /// Backed by byte with OwnerOnly = 0 so LevelData assets baked before this
+ /// existed deserialize to the pre-existing behaviour without needing a re-bake.
+ ///
+ /// Tower OWNERSHIP is unaffected: a tower belongs to whoever paid for it, and sell /
+ /// upgrade stay owner-gated in both modes.
+ ///
+ public enum BuildAccess : byte
+ {
+ /// A player may only build on tiles covered by their own PlayerZoneVolume.
+ OwnerOnly = 0,
+
+ /// Any player may build on any Buildable tile, whichever zone owns it.
+ Shared = 1,
+ }
+
///
/// Outcome of a bake operation, recorded on the baked asset.
///
diff --git a/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs b/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs
index dac565b..a759032 100644
--- a/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs
+++ b/Assets/_Project/Scripts/Editor/Levels/LevelBakePipeline.cs
@@ -802,17 +802,33 @@ namespace TD.Levels.Editor
}
// P5-8: zones with neither outgoing leak nor goal adjacency.
- var zonesWithLeaks = new HashSet();
- foreach (var l in ctx.LeakExitVolumes) zonesWithLeaks.Add(l.sourceZone);
-
- foreach (var owner in ctx.DeclaredOwners)
+ //
+ // OwnerOnly maps only. The rule asserts the lane-chain topology those maps are built
+ // around: each player's zone either hands off to the next or is the final defender.
+ //
+ // On a Shared map that assertion is wrong, not merely unnecessary. Zones there are
+ // typically directly adjacent with no gate between them, so most have no outgoing leak
+ // and are not goal-adjacent — and that is the intended shape, because the whole map is
+ // one contiguous maze. The property P5-8 actually protects ("enemies from this zone have
+ // somewhere to go") is enforced more strictly by P5-4 above, which runs a real BFS from
+ // every spawner to the exit set — and with no leak volumes present, that exit set is the
+ // goal tiles, which is exactly the right requirement. Zones with no spawners can't
+ // strand anything: WaveManager skips them.
+ if (ctx.Authoring.buildAccess == BuildAccess.OwnerOnly)
{
- bool hasLeak = zonesWithLeaks.Contains(owner);
- bool isGoalAdj = goalAdjacentZones.Contains(owner);
- if (!hasLeak && !isGoalAdj)
+ var zonesWithLeaks = new HashSet();
+ foreach (var l in ctx.LeakExitVolumes) zonesWithLeaks.Add(l.sourceZone);
+
+ foreach (var owner in ctx.DeclaredOwners)
{
- report.Error("P5-8", $"Player zone {owner} has no outgoing leak exit AND is not goal-adjacent. " +
- "Every zone must either lead somewhere or be a final defender.");
+ bool hasLeak = zonesWithLeaks.Contains(owner);
+ bool isGoalAdj = goalAdjacentZones.Contains(owner);
+ if (!hasLeak && !isGoalAdj)
+ {
+ report.Error("P5-8", $"Player zone {owner} has no outgoing leak exit AND is not goal-adjacent. " +
+ "Every zone must either lead somewhere or be a final defender. " +
+ "(This rule is skipped on Shared-build maps.)");
+ }
}
}
@@ -919,6 +935,7 @@ namespace TD.Levels.Editor
data.PlayerCount = ctx.Authoring.playerCount;
data.MapDescription = ctx.Authoring.mapDescription;
data.Author = ctx.Authoring.author;
+ data.BuildAccess = ctx.Authoring.buildAccess;
data.GridOriginTile = ctx.GridOriginTile;
data.GridSize = ctx.GridSize;
@@ -1152,7 +1169,10 @@ namespace TD.Levels.Editor
sb.Append("playerCount=").Append(ctx.Authoring.playerCount.ToString(inv)).Append('|');
sb.Append("expectedGoalCount=").Append(ctx.Authoring.expectedGoalCount.ToString(inv)).Append('|');
sb.Append("mapDescription=").Append(ctx.Authoring.mapDescription ?? "").Append('|');
- sb.Append("author=").Append(ctx.Authoring.author ?? "").Append('\n');
+ sb.Append("author=").Append(ctx.Authoring.author ?? "").Append('|');
+ // By NAME, matching the per-volume enum convention below — a future reordering of the
+ // enum must not silently produce a matching hash for different rules.
+ sb.Append("buildAccess=").Append(ctx.Authoring.buildAccess.ToString()).Append('\n');
// Volume blocks, ordered by canonical path.
var rootTransform = ctx.Authoring.transform;
@@ -1354,6 +1374,7 @@ namespace TD.Levels.Editor
target.PlayerCount = src.PlayerCount;
target.MapDescription = src.MapDescription;
target.Author = src.Author;
+ target.BuildAccess = src.BuildAccess;
target.ScenePath = src.ScenePath;
target.AuthoringHash = src.AuthoringHash;
target.LastBakeTimestamp = src.LastBakeTimestamp;
diff --git a/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs
new file mode 100644
index 0000000..43fc91c
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs
@@ -0,0 +1,356 @@
+// Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEditorInternal;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+using TD.Audio;
+using TD.Dev;
+using TD.Gameplay;
+using TD.Gameplay.BuilderEffects;
+using TD.Gameplay.BuilderSpells;
+using TD.Gameplay.Draft;
+using TD.Gameplay.EnemyAbilities;
+using TD.Gameplay.EnemyUpgrades;
+using TD.Gameplay.Waves;
+using TD.UI;
+using TD.VFX;
+
+namespace TD.Levels.Editor
+{
+ ///
+ /// One-time (re-runnable) utility that lifts every map-independent scene object out of a
+ /// reference match scene and bakes it into the two prefabs TD/New Map… instantiates.
+ ///
+ ///
+ /// Why extract instead of generating from scratch? Several of these components hold
+ /// ORDER-SENSITIVE arrays that double as network identity — EnemyUpgradePool.options
+ /// indices are card network ids, and TowerPlacementManager.towerDefinitions indices are
+ /// TowerTypeId. Re-deriving those from an AssetDatabase scan would produce a different
+ /// order than the shipping map and desync peers. Copying the live components preserves them
+ /// exactly.
+ ///
+ /// Two prefabs, two lifetimes. MatchServices contains no NetworkObject, so
+ /// new maps keep it as a LINKED prefab instance and later edits propagate everywhere.
+ /// MatchNetwork holds the six scene-placed NetworkBehaviours and is UNPACKED on use, so
+ /// what NGO sees in a generated scene is indistinguishable from a hand-authored one.
+ ///
+ /// This does not modify the reference scene's contents — temporary objects are
+ /// created and destroyed — but Unity still marks the scene dirty. Don't save it afterwards.
+ ///
+ public static class MapCoreExtractor
+ {
+ private const string PrefabFolder = "Assets/_Project/Prefabs/MatchCore";
+ private const string ServicesPrefabPath = PrefabFolder + "/MatchServices.prefab";
+ private const string NetworkPrefabPath = PrefabFolder + "/MatchNetwork.prefab";
+
+ // Plain (non-networked, no UIDocument) singleton services, collapsed onto the
+ // _MatchServices ROOT GameObject in this order.
+ //
+ // Order matters in exactly one place: AudioSource must precede MusicPlayer, whose
+ // [RequireComponent(typeof(AudioSource))] would otherwise auto-add a second, default-valued
+ // AudioSource before we get a chance to copy the authored one.
+ private static readonly System.Type[] RootServiceTypes =
+ {
+ typeof(LevelLoader),
+ typeof(PathfindingService),
+ typeof(SelectionState),
+ typeof(SelectionVisualizer),
+ typeof(TowerPlacementController),
+ typeof(TowerPaintController),
+ typeof(BuilderSpellCastController),
+ typeof(FloatingTextSpawner),
+ typeof(SellEffectSpawner),
+ typeof(AudioManager),
+ typeof(AudioSource), // must come before MusicPlayer — see note above
+ typeof(MusicPlayer),
+ typeof(BuilderEffectPool),
+ typeof(BuilderSpellPool),
+ typeof(EnemyAbilityPool),
+ typeof(EnemyUpgradePool),
+ typeof(DraftPool),
+ typeof(DraftService),
+ typeof(DevWaveControls),
+ };
+
+ // Scene-placed NetworkBehaviours. Each keeps its own GameObject and its own NetworkObject —
+ // they are only re-parented under a shared root, so network topology is unchanged.
+ private static readonly System.Type[] NetworkServiceTypes =
+ {
+ typeof(ChatService),
+ typeof(MatchState),
+ typeof(RunState),
+ typeof(TowerPlacementManager),
+ typeof(WaveManager),
+ typeof(WaveVote),
+ };
+
+ // -------------------------------------------------------------------
+ // Menu entry
+ // -------------------------------------------------------------------
+
+ [MenuItem("TD/Map Pipeline/Build Core Prefabs From Open Scene", false, 200)]
+ public static void BuildCorePrefabs()
+ {
+ Scene scene = EditorSceneManager.GetActiveScene();
+
+ if (!scene.IsValid() || string.IsNullOrEmpty(scene.path))
+ {
+ EditorUtility.DisplayDialog(
+ "No saved scene open",
+ "Open a fully-wired match scene (9Player) before running this. The extractor " +
+ "reads its components to build the core prefabs.",
+ "OK");
+ return;
+ }
+
+ // Pre-scan so a missing service aborts before we create anything.
+ if (!TryResolveSources(scene, out var rootSources, out var missing))
+ {
+ EditorUtility.DisplayDialog(
+ "Reference scene is incomplete",
+ $"'{scene.name}' is missing {missing.Count} component(s) the core prefabs need:\n\n" +
+ string.Join("\n", missing) +
+ "\n\nOpen a complete match scene (9Player) and try again.",
+ "OK");
+ return;
+ }
+
+ bool proceed = EditorUtility.DisplayDialog(
+ "Build core prefabs",
+ $"Read '{scene.name}' and (re)write:\n\n" +
+ $" {ServicesPrefabPath}\n" +
+ $" {NetworkPrefabPath}\n\n" +
+ "The scene's own contents are not changed, but Unity will mark it dirty. " +
+ "Don't save it afterwards.\n\nProceed?",
+ "Build Prefabs",
+ "Cancel");
+ if (!proceed) return;
+
+ MapTemplate.EnsureFolder(PrefabFolder);
+
+ GameObject servicesPrefab = BuildServicesPrefab(scene, rootSources);
+ GameObject networkPrefab = BuildNetworkPrefab(scene);
+
+ var template = MapTemplate.LoadOrCreate();
+ template.matchServicesPrefab = servicesPrefab;
+ template.matchNetworkPrefab = networkPrefab;
+ CaptureTerrainDefaults(scene, template);
+ EditorUtility.SetDirty(template);
+
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+
+ Debug.Log(
+ $"[MapPipeline] Core prefabs built from '{scene.name}'.\n" +
+ $" MatchServices: {RootServiceTypes.Length} components on the root + HUD / DebugConsole / " +
+ $"CameraRig / lighting children.\n" +
+ $" MatchNetwork: {NetworkServiceTypes.Length} NetworkBehaviours under one root.\n" +
+ $" Template: {MapTemplate.AssetPath}\n" +
+ $" '{scene.name}' is now marked dirty by the temporary objects — do NOT save it.");
+
+ EditorGUIUtility.PingObject(template);
+ }
+
+ // -------------------------------------------------------------------
+ // Source resolution
+ // -------------------------------------------------------------------
+
+ // Resolves every root-service component up front. Returns false (with a human-readable list)
+ // if anything is absent, so we never write a half-populated prefab.
+ private static bool TryResolveSources(Scene scene, out List rootSources,
+ out List missing)
+ {
+ rootSources = new List(RootServiceTypes.Length);
+ missing = new List();
+
+ // AudioSource is resolved from MusicPlayer's GameObject rather than "first in scene",
+ // so we copy the music source's authored volume rather than some unrelated emitter.
+ var musicPlayer = FindOne(scene, typeof(MusicPlayer)) as MusicPlayer;
+
+ foreach (var type in RootServiceTypes)
+ {
+ Component found = type == typeof(AudioSource)
+ ? (musicPlayer != null ? musicPlayer.GetComponent() : null)
+ : FindOne(scene, type);
+
+ if (found == null) missing.Add(" • " + type.Name);
+ rootSources.Add(found);
+ }
+
+ foreach (var type in NetworkServiceTypes)
+ {
+ if (FindOne(scene, type) == null) missing.Add(" • " + type.Name);
+ }
+
+ if (FindOne(scene, typeof(HUDController)) == null) missing.Add(" • HUDController");
+ if (FindOne(scene, typeof(CameraController)) == null) missing.Add(" • CameraController");
+
+ return missing.Count == 0;
+ }
+
+ // Scans the scene's root objects rather than Object.FindObjectsByType: the FindObjectsByType
+ // overload set has churned across Unity 6.x (FindObjectsSortMode deprecation), and walking
+ // roots is stable across all of them.
+ private static Component FindOne(Scene scene, System.Type type)
+ {
+ foreach (var root in scene.GetRootGameObjects())
+ {
+ var found = root.GetComponentInChildren(type, true);
+ if (found != null) return found;
+ }
+ return null;
+ }
+
+ private static Light FindDirectionalLight(Scene scene)
+ {
+ foreach (var root in scene.GetRootGameObjects())
+ {
+ foreach (var light in root.GetComponentsInChildren(true))
+ {
+ if (light.type == LightType.Directional) return light;
+ }
+ }
+ return null;
+ }
+
+ // -------------------------------------------------------------------
+ // MatchServices prefab
+ // -------------------------------------------------------------------
+
+ private static GameObject BuildServicesPrefab(Scene scene, List rootSources)
+ {
+ var root = new GameObject("_MatchServices");
+
+ // Flatten every plain service onto the root. CopyComponent/PasteComponentAsNew carries
+ // all serialized values, including the order-sensitive asset arrays.
+ for (int i = 0; i < rootSources.Count; i++)
+ {
+ var src = rootSources[i];
+ if (src == null) continue;
+ ComponentUtility.CopyComponent(src);
+ ComponentUtility.PasteComponentAsNew(root);
+ }
+
+ // Components that need their own GameObject: UIDocument is [DisallowMultipleComponent],
+ // so HUD and DebugConsole can't share one; CameraRig needs an independently-moving
+ // transform with the Camera as its child.
+ GameObject hud = CloneUnder(FindOne(scene, typeof(HUDController)), root, "HUD");
+ CloneUnder(FindOne(scene, typeof(DebugConsole)), root, "DebugConsole");
+ GameObject cameraRig = CloneUnder(FindOne(scene, typeof(CameraController)), root, "CameraRig");
+ CloneUnder(FindDirectionalLight(scene), root, "Directional Light");
+
+ // Post-processing volume is optional — 9Player doesn't have one, Main does.
+ CloneUnder(FindOne(scene, typeof(UnityEngine.Rendering.Volume)), root, "Global Volume");
+
+ RewireHudReferences(hud, root, cameraRig);
+ ClearBakedLevelReference(root);
+
+ var prefab = PrefabUtility.SaveAsPrefabAsset(root, ServicesPrefabPath);
+ Object.DestroyImmediate(root);
+ return prefab;
+ }
+
+ // Instantiate() remaps references that point INSIDE the copied hierarchy but leaves
+ // references that point outside it aimed at the original scene objects. Saving a prefab
+ // silently nulls those, so re-aim them at the prefab-internal equivalents first.
+ private static void RewireHudReferences(GameObject hud, GameObject root, GameObject cameraRig)
+ {
+ if (hud == null) return;
+ var controller = hud.GetComponent();
+ if (controller == null) return;
+
+ var so = new SerializedObject(controller);
+ SetRef(so, "placementController", root.GetComponent());
+ SetRef(so, "paintController", root.GetComponent());
+ SetRef(so, "cameraController",
+ cameraRig != null ? cameraRig.GetComponent() : null);
+
+ // TowerPlacementManager lives in the OTHER prefab (it's a NetworkBehaviour), so this
+ // reference cannot be satisfied here. HUDController already falls back to
+ // TowerPlacementManager.Instance and retries per-frame until the object spawns, so
+ // leaving it null is the correct wiring, not a gap.
+ SetRef(so, "placementManager", null);
+
+ so.ApplyModifiedPropertiesWithoutUndo();
+ }
+
+ // The reference scene's LevelLoader points at that map's LevelData. The prefab is map-
+ // independent, so blank it — NewMapBuilder sets it per-instance as a prefab override.
+ private static void ClearBakedLevelReference(GameObject root)
+ {
+ var loader = root.GetComponent();
+ if (loader == null) return;
+
+ var so = new SerializedObject(loader);
+ SetRef(so, "level", null);
+ so.ApplyModifiedPropertiesWithoutUndo();
+ }
+
+ // -------------------------------------------------------------------
+ // MatchNetwork prefab
+ // -------------------------------------------------------------------
+
+ private static GameObject BuildNetworkPrefab(Scene scene)
+ {
+ var root = new GameObject("_MatchNetwork");
+
+ foreach (var type in NetworkServiceTypes)
+ {
+ CloneUnder(FindOne(scene, type), root, type.Name);
+ }
+
+ var prefab = PrefabUtility.SaveAsPrefabAsset(root, NetworkPrefabPath);
+ Object.DestroyImmediate(root);
+ return prefab;
+ }
+
+ // -------------------------------------------------------------------
+ // Terrain defaults
+ // -------------------------------------------------------------------
+
+ private static void CaptureTerrainDefaults(Scene scene, MapTemplate template)
+ {
+ var terrain = FindOne(scene, typeof(Terrain)) as Terrain;
+ if (terrain == null) return;
+
+ if (terrain.materialTemplate != null) template.terrainMaterial = terrain.materialTemplate;
+ if (terrain.terrainData != null && terrain.terrainData.terrainLayers != null &&
+ terrain.terrainData.terrainLayers.Length > 0)
+ {
+ template.terrainLayers = terrain.terrainData.terrainLayers;
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Helpers
+ // -------------------------------------------------------------------
+
+ // Clones the component's whole GameObject subtree and parents it under root.
+ // Returns null (silently) when source is null — callers treat those as optional.
+ private static GameObject CloneUnder(Component source, GameObject root, string name)
+ {
+ if (source == null) return null;
+
+ var clone = Object.Instantiate(source.gameObject);
+ clone.name = name;
+ clone.transform.SetParent(root.transform, worldPositionStays: false);
+ return clone;
+ }
+
+ private static void SetRef(SerializedObject so, string propertyPath, Object value)
+ {
+ var prop = so.FindProperty(propertyPath);
+ if (prop == null)
+ {
+ Debug.LogWarning($"[MapPipeline] Serialized field '{propertyPath}' not found on " +
+ $"{so.targetObject.GetType().Name}. It was probably renamed — " +
+ "update MapCoreExtractor.");
+ return;
+ }
+ prop.objectReferenceValue = value;
+ }
+ }
+}
diff --git a/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta
new file mode 100644
index 0000000..7dfcd04
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/MapCoreExtractor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: d1b948bcbbe8d8b4788f2056372280b3
\ No newline at end of file
diff --git a/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs
new file mode 100644
index 0000000..0d112c0
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs
@@ -0,0 +1,292 @@
+// Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs
+using UnityEditor;
+using UnityEngine;
+
+namespace TD.Levels.Editor
+{
+ ///
+ /// Editor-only settings asset that drives TD/New Map…. Holds the two core prefabs
+ /// produced by plus every default the new-map generator needs,
+ /// so tuning the starter layout is an inspector edit rather than a code change.
+ ///
+ ///
+ /// Lives in the Editor assembly deliberately — nothing at runtime reads it, and keeping the
+ /// type editor-only stops it from being pulled into a player build.
+ ///
+ /// The asset is created on demand at . If it goes missing, both
+ /// TD/New Map… and the extractor recreate it with defaults; only the prefab references
+ /// and captured terrain settings are lost, and re-running the extractor restores those.
+ ///
+ public class MapTemplate : ScriptableObject
+ {
+ public const string AssetPath = "Assets/_Project/Settings/MapTemplate.asset";
+
+ // -------------------------------------------------------------------
+ // Core prefabs. Populated by MapCoreExtractor; consumed by NewMapBuilder.
+ // -------------------------------------------------------------------
+
+ [Header("Core Prefabs (built by TD/Map Pipeline/Build Core Prefabs)")]
+ [Tooltip("Every map-independent, non-networked service collapsed onto one GameObject " +
+ "(plus HUD / DebugConsole / CameraRig / light children). Instantiated as a LINKED " +
+ "prefab instance so edits here propagate to every map.")]
+ public GameObject matchServicesPrefab;
+
+ [Tooltip("The six scene-placed NetworkBehaviours, parented under one root. Instantiated " +
+ "and immediately UNPACKED so the scene contains plain GameObjects — network " +
+ "topology stays byte-identical to hand-authored maps.")]
+ public GameObject matchNetworkPrefab;
+
+ // -------------------------------------------------------------------
+ // Output locations.
+ // -------------------------------------------------------------------
+
+ [Header("Output Locations")]
+ [Tooltip("Folder new map scenes, their LevelData, and their TerrainData are written to. " +
+ "Drag the folder itself here — an asset reference follows renames and moves, " +
+ "which a path string does not.")]
+ public DefaultAsset sceneFolderAsset;
+
+ [Tooltip("Scene holding the MapRegistry that the lobby's map browser reads. New maps are " +
+ "appended to its Maps array automatically.")]
+ public SceneAsset mainMenuScene;
+
+ // Legacy path strings, superseded by the asset references above. Kept so an existing
+ // template migrates itself (see MigratePathsToAssets) and as a last resort if a reference
+ // is cleared. Hidden so there's exactly one obvious place to edit.
+ [HideInInspector] public string sceneFolder = "Assets/_Project/Scenes/Levels";
+ [HideInInspector] public string mainMenuScenePath = "Assets/_Project/Scenes/UI/MainMenu.unity";
+
+ ///
+ /// Folder new maps are written to. Prefers ; falls back to the
+ /// legacy path string if the reference is unset or doesn't point at a folder.
+ ///
+ public string SceneFolderPath
+ {
+ get
+ {
+ if (sceneFolderAsset != null)
+ {
+ string path = AssetDatabase.GetAssetPath(sceneFolderAsset);
+ if (AssetDatabase.IsValidFolder(path)) return path;
+
+ Debug.LogWarning($"[MapPipeline] MapTemplate's Scene Folder Asset points at " +
+ $"'{path}', which is not a folder. Falling back to '{sceneFolder}'.");
+ }
+ return sceneFolder;
+ }
+ }
+
+ ///
+ /// Scene containing the MapRegistry. Prefers ; falls back to the
+ /// legacy path string. Returns empty if neither resolves.
+ ///
+ public string MainMenuScenePath
+ {
+ get
+ {
+ if (mainMenuScene != null)
+ {
+ string path = AssetDatabase.GetAssetPath(mainMenuScene);
+ if (!string.IsNullOrEmpty(path)) return path;
+ }
+ return mainMenuScenePath ?? string.Empty;
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Terrain defaults. Captured from the reference scene by the extractor.
+ // -------------------------------------------------------------------
+
+ [Header("Terrain Defaults")]
+ [Tooltip("Material applied to new terrain. Captured from the reference scene's Terrain.")]
+ public Material terrainMaterial;
+
+ [Tooltip("Terrain layers (splat textures) applied to new terrain.")]
+ public TerrainLayer[] terrainLayers;
+
+ [Tooltip("Heightmap resolution. Must be 2^n + 1 (129, 257, 513, 1025…).")]
+ public int terrainHeightmapResolution = 513;
+
+ [Tooltip("Total vertical range of the terrain in world units.")]
+ public float terrainHeight = 60f;
+
+ [Tooltip("How far the terrain extends past the map bounds on each side, in tiles. Gives " +
+ "the camera something to look at beyond the playable area.")]
+ public int terrainSkirtTiles = 20;
+
+ [Tooltip("Terrain is created flattened to this height above its own base, and its transform " +
+ "is dropped by the same amount — so the flat surface lands exactly on the buildable " +
+ "plane (Y=0) while leaving headroom to carve DOWN as well as up. Set 0 to match the " +
+ "older 9Player setup (surface at the very bottom of the height range).")]
+ public float terrainCarveDepth = 5f;
+
+ // -------------------------------------------------------------------
+ // Starter layout. All values in tiles.
+ // -------------------------------------------------------------------
+
+ [Header("Starter Layout (tiles)")]
+ [Tooltip("Default map width for the New Map dialog.")]
+ public int defaultMapWidth = 60;
+
+ [Tooltip("Default map height for the New Map dialog.")]
+ public int defaultMapHeight = 70;
+
+ [Tooltip("Gap between the map edge (MapAreaVolume) and the gameplay volumes. The map area " +
+ "must fully contain every gameplay volume, and the buffer gives the camera room " +
+ "to pan past the playfield.")]
+ public int playAreaMargin = 4;
+
+ [Tooltip("Depth (north-south) of the GoalVolume.")]
+ public int goalDepth = 5;
+
+ [Tooltip("Width (east-west) of the GoalVolume.")]
+ public int goalWidth = 10;
+
+ [Tooltip("Depth of each SpawnerVolume, measured from the south edge of its owner's band.")]
+ public int spawnerDepth = 3;
+
+ [Tooltip("Width of each SpawnerVolume.")]
+ public int spawnerWidth = 10;
+
+ [Tooltip("Width of the one-tile-deep LeakExitVolume gate between adjacent player bands.")]
+ public int leakGateWidth = 8;
+
+ [Tooltip("Smallest acceptable north-south depth for a player band. The New Map dialog " +
+ "refuses to generate a layout thinner than this and tells you the map height needed.")]
+ public int minBandDepth = 8;
+
+ // -------------------------------------------------------------------
+ // Loading
+ // -------------------------------------------------------------------
+
+ ///
+ /// Returns the template asset, creating it with defaults if it doesn't exist yet.
+ /// Never returns null.
+ ///
+ public static MapTemplate LoadOrCreate()
+ {
+ var existing = AssetDatabase.LoadAssetAtPath(AssetPath);
+ if (existing != null)
+ {
+ existing.MigratePathsToAssets();
+ return existing;
+ }
+
+ EnsureFolder(System.IO.Path.GetDirectoryName(AssetPath).Replace("\\", "/"));
+
+ var created = CreateInstance();
+ AssetDatabase.CreateAsset(created, AssetPath);
+ created.MigratePathsToAssets();
+ AssetDatabase.SaveAssets();
+ Debug.Log($"[MapPipeline] Created default map template at '{AssetPath}'.");
+ return created;
+ }
+
+ ///
+ /// Upgrades a template that still stores locations as path strings, resolving each to an
+ /// asset reference. Idempotent and cheap — safe to call on every load.
+ ///
+ ///
+ /// If the recorded path no longer resolves (the folder was renamed out from under it, which
+ /// is exactly the failure the asset references exist to prevent), falls back to searching
+ /// the project for a uniquely-named match. An ambiguous match is left unresolved on purpose:
+ /// guessing which of several same-named scenes holds the MapRegistry would be worse than
+ /// asking.
+ ///
+ private void MigratePathsToAssets()
+ {
+ bool changed = false;
+
+ if (sceneFolderAsset == null && !string.IsNullOrEmpty(sceneFolder)
+ && AssetDatabase.IsValidFolder(sceneFolder))
+ {
+ sceneFolderAsset = AssetDatabase.LoadAssetAtPath(sceneFolder);
+ changed |= sceneFolderAsset != null;
+ }
+
+ if (mainMenuScene == null && !string.IsNullOrEmpty(mainMenuScenePath))
+ {
+ var scene = AssetDatabase.LoadAssetAtPath(mainMenuScenePath);
+
+ if (scene == null)
+ {
+ string wanted = System.IO.Path.GetFileNameWithoutExtension(mainMenuScenePath);
+ scene = FindUniqueSceneNamed(wanted);
+ if (scene != null)
+ {
+ Debug.Log($"[MapPipeline] MapTemplate's recorded Main Menu path " +
+ $"'{mainMenuScenePath}' no longer exists; relinked to " +
+ $"'{AssetDatabase.GetAssetPath(scene)}'.");
+ }
+ }
+
+ if (scene != null)
+ {
+ mainMenuScene = scene;
+ changed = true;
+ }
+ }
+
+ if (changed)
+ {
+ EditorUtility.SetDirty(this);
+ AssetDatabase.SaveAssets();
+ }
+ }
+
+ // Returns the one SceneAsset whose file name matches exactly, or null if there are zero or
+ // several. Name search only — the caller has already failed to resolve by path.
+ private static SceneAsset FindUniqueSceneNamed(string sceneName)
+ {
+ if (string.IsNullOrEmpty(sceneName)) return null;
+
+ string[] guids = AssetDatabase.FindAssets($"{sceneName} t:SceneAsset");
+ SceneAsset first = null;
+ int matches = 0;
+
+ foreach (string guid in guids)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ if (!string.Equals(System.IO.Path.GetFileNameWithoutExtension(path), sceneName,
+ System.StringComparison.OrdinalIgnoreCase))
+ {
+ continue; // FindAssets does substring matching; we want an exact file name.
+ }
+
+ matches++;
+ if (first == null) first = AssetDatabase.LoadAssetAtPath(path);
+ }
+
+ if (matches > 1)
+ {
+ Debug.LogWarning($"[MapPipeline] Found {matches} scenes named '{sceneName}'. " +
+ "Assign Main Menu Scene on MapTemplate manually.");
+ return null;
+ }
+
+ return first;
+ }
+
+ ///
+ /// Creates and any missing ancestors. Path is asset-relative and
+ /// uses forward slashes ("Assets/_Project/Prefabs/MatchCore"). No-op if it already exists.
+ ///
+ public static void EnsureFolder(string folder)
+ {
+ if (string.IsNullOrEmpty(folder) || AssetDatabase.IsValidFolder(folder)) return;
+
+ string[] parts = folder.Split('/');
+ // parts[0] is always "Assets" for a valid asset path; walk down creating as needed.
+ string running = parts[0];
+ for (int i = 1; i < parts.Length; i++)
+ {
+ string next = running + "/" + parts[i];
+ if (!AssetDatabase.IsValidFolder(next))
+ {
+ AssetDatabase.CreateFolder(running, parts[i]);
+ }
+ running = next;
+ }
+ }
+ }
+}
diff --git a/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta
new file mode 100644
index 0000000..7fbc813
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/MapTemplate.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: fb7355881928ea146a26471078f207c2
\ No newline at end of file
diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs
new file mode 100644
index 0000000..737e97b
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs
@@ -0,0 +1,578 @@
+// Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+using TD.Core;
+using TD.Gameplay;
+
+namespace TD.Levels.Editor
+{
+ ///
+ /// Everything the TD/New Map… command does once the designer presses Create: build the
+ /// scene, generate a starter volume layout that bakes clean, create and wire the LevelData, and
+ /// perform the three registration steps that otherwise fail silently (Build Settings, the
+ /// LevelLoader reference, and the lobby's MapRegistry).
+ ///
+ ///
+ /// The generated scene has four roots — _LevelAuthoring, _MatchServices,
+ /// _MatchNetwork, Terrain — replacing the ~30 the hand-authored maps carry.
+ ///
+ public static class NewMapBuilder
+ {
+ // The physics layer terrain must sit on. Builder.SampleTerrainY and
+ // BuilderSpellCastController both raycast against it; terrain left on Default silently
+ // falls back to Y=0 and the builder walks through hills instead of over them.
+ private const string TerrainLayerName = "TerrainGeometry";
+
+ // Vertical size of every authoring volume's BoxCollider. Any value works so long as the
+ // bounds straddle Y=0 (bake rule P2-18); 1 unit centred on zero matches 9Player.
+ private const float VolumeHeight = 1f;
+
+ private static readonly Regex ValidName = new Regex(@"^[A-Za-z0-9_]+$");
+
+ // -------------------------------------------------------------------
+ // Request
+ // -------------------------------------------------------------------
+
+ public class Request
+ {
+ public string MapName = "NewMap";
+ public int PlayerCount = 3;
+ public int MapWidth = 60;
+ public int MapHeight = 70;
+ public string Author = "";
+ public string Description = "";
+ public BuildAccess BuildAccess = BuildAccess.OwnerOnly;
+ public bool CreateTerrain = true;
+ public bool AddToBuildSettings = true;
+ public bool AddToMapRegistry = true;
+ public bool BakeImmediately = true;
+ }
+
+ // -------------------------------------------------------------------
+ // Starter layout
+ // -------------------------------------------------------------------
+
+ ///
+ /// Tile rectangles for a generated starter map. Zones are stacked south-to-north as
+ /// full-width bands; enemies spawn at the south edge of their owner's band and travel north
+ /// through a one-tile leak gate into the next player's band, with the goal north of the
+ /// final band.
+ ///
+ public struct Layout
+ {
+ public RectInt MapArea;
+ public RectInt[] Zones; // index 0 = Player1
+ public RectInt[] Spawners; // parallel to Zones
+ public RectInt[] Leaks; // Zones.Length - 1 entries; Leaks[i] runs zone i -> zone i+1
+ public RectInt Goal;
+ public int BandDepth;
+ }
+
+ ///
+ /// Computes the starter layout, or explains why the requested dimensions can't hold one.
+ /// Pure — safe to call every OnGUI frame for live validation.
+ ///
+ public static bool TryComputeLayout(MapTemplate template, int mapWidth, int mapHeight,
+ int playerCount, BuildAccess buildAccess,
+ out Layout layout, out string error)
+ {
+ layout = default;
+ error = null;
+
+ // OwnerOnly maps get a one-tile leak gate between bands: it is the only walkable
+ // connection, which is what forces enemies through a chokepoint and makes the handoff
+ // between lanes legible. Shared maps skip gates entirely and butt the bands together —
+ // the whole map is one maze, so a gate would just be an arbitrary pinch, and with no
+ // LeakExitVolume the gap row would not be walkable at all.
+ bool useLeakGates = buildAccess == BuildAccess.OwnerOnly;
+ int gapRows = useLeakGates ? playerCount - 1 : 0;
+
+ int margin = Mathf.Max(0, template.playAreaMargin);
+ int playX0 = margin;
+ int playY0 = margin;
+ int playW = mapWidth - margin * 2;
+ int playH = mapHeight - margin * 2;
+
+ int widestFeature = Mathf.Max(template.goalWidth,
+ Mathf.Max(template.spawnerWidth, template.leakGateWidth));
+ if (playW < widestFeature)
+ {
+ error = $"Map is too narrow. The play area is {playW} tiles wide after the " +
+ $"{margin}-tile margin, but the widest starter feature needs {widestFeature}. " +
+ $"Use a width of at least {widestFeature + margin * 2}.";
+ return false;
+ }
+
+ // Vertical budget: N bands + the gate rows (if any) + the goal.
+ int budget = playH - gapRows - template.goalDepth;
+ int bandDepth = playerCount > 0 ? budget / playerCount : 0;
+
+ int minBand = Mathf.Max(template.minBandDepth, template.spawnerDepth + 1);
+ if (bandDepth < minBand)
+ {
+ int required = playerCount * minBand + gapRows
+ + template.goalDepth + margin * 2;
+ error = $"Map is too shallow for {playerCount} player band(s). Each band would be " +
+ $"{Mathf.Max(bandDepth, 0)} tiles deep; the minimum is {minBand}. " +
+ $"Use a height of at least {required}.";
+ return false;
+ }
+
+ layout.MapArea = new RectInt(0, 0, mapWidth, mapHeight);
+ layout.BandDepth = bandDepth;
+ layout.Zones = new RectInt[playerCount];
+ layout.Spawners = new RectInt[playerCount];
+ layout.Leaks = new RectInt[useLeakGates ? Mathf.Max(0, playerCount - 1) : 0];
+
+ int y = playY0;
+ for (int i = 0; i < playerCount; i++)
+ {
+ layout.Zones[i] = new RectInt(playX0, y, playW, bandDepth);
+
+ // Spawner sits at the south edge of its own band, so enemies always have the full
+ // band depth to walk through before reaching the exit (bake rule P5-5 wants it
+ // inside the owner's zone).
+ int spawnW = Mathf.Min(template.spawnerWidth, playW);
+ layout.Spawners[i] = new RectInt(
+ CenteredStart(playX0, playW, spawnW), y, spawnW, template.spawnerDepth);
+
+ y += bandDepth;
+
+ if (useLeakGates && i < playerCount - 1)
+ {
+ // One-tile gate wedged between two bands: its south neighbours are band i and
+ // its north neighbours are band i+1, satisfying both adjacency rules (P5-6/P5-7).
+ int gateW = Mathf.Min(template.leakGateWidth, playW);
+ layout.Leaks[i] = new RectInt(
+ CenteredStart(playX0, playW, gateW), y, gateW, 1);
+ y += 1;
+ }
+ }
+
+ int goalW = Mathf.Min(template.goalWidth, playW);
+ layout.Goal = new RectInt(
+ CenteredStart(playX0, playW, goalW), y, goalW, template.goalDepth);
+
+ return true;
+ }
+
+ private static int CenteredStart(int areaStart, int areaWidth, int featureWidth)
+ {
+ return areaStart + (areaWidth - featureWidth) / 2;
+ }
+
+ // -------------------------------------------------------------------
+ // Creation
+ // -------------------------------------------------------------------
+
+ ///
+ /// Creates the map. Returns false with a human-readable reason on any precondition failure;
+ /// nothing is written to disk in that case.
+ ///
+ public static bool Create(Request request, out string error)
+ {
+ error = null;
+ var template = MapTemplate.LoadOrCreate();
+
+ if (!ValidatePreconditions(request, template, out error)) return false;
+
+ if (!TryComputeLayout(template, request.MapWidth, request.MapHeight,
+ request.PlayerCount, request.BuildAccess,
+ out Layout layout, out error))
+ {
+ return false;
+ }
+
+ string folder = template.SceneFolderPath;
+ string scenePath = $"{folder}/{request.MapName}.unity";
+ string dataPath = $"{folder}/{request.MapName}.asset";
+
+ // Give the designer a chance to save whatever they had open — NewScene(Single) would
+ // otherwise discard it.
+ if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
+ {
+ error = "Cancelled while saving the currently open scene.";
+ return false;
+ }
+
+ MapTemplate.EnsureFolder(folder);
+
+ Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
+
+ // ---- Core objects -------------------------------------------
+ var services = (GameObject)PrefabUtility.InstantiatePrefab(template.matchServicesPrefab);
+ services.name = "_MatchServices";
+
+ var network = (GameObject)PrefabUtility.InstantiatePrefab(template.matchNetworkPrefab);
+ network.name = "_MatchNetwork";
+ // Unpack so the six NetworkObjects are plain scene objects. NGO treats in-scene placed
+ // NetworkObjects that are prefab instances differently from loose ones; unpacking keeps
+ // generated maps structurally identical to the hand-authored ones.
+ PrefabUtility.UnpackPrefabInstance(
+ network, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
+
+ // ---- LevelData ----------------------------------------------
+ var levelData = ScriptableObject.CreateInstance();
+ AssetDatabase.CreateAsset(levelData, dataPath);
+
+ // ---- Authoring hierarchy ------------------------------------
+ LevelAuthoring authoring = BuildAuthoring(request, layout, levelData);
+
+ // ---- Terrain -------------------------------------------------
+ if (request.CreateTerrain)
+ {
+ CreateTerrain(request, template);
+ }
+
+ // ---- Wire the runtime loader ---------------------------------
+ // LevelLoader lives inside the linked MatchServices prefab; assigning here records a
+ // per-instance override, which is exactly the intent — the asset differs per map.
+ WireLevelLoader(services, levelData);
+
+ // ---- Save + register -----------------------------------------
+ EditorSceneManager.SaveScene(scene, scenePath);
+
+ var notes = new List();
+
+ if (request.AddToBuildSettings) notes.Add(RegisterInBuildSettings(scenePath));
+ if (request.AddToMapRegistry) notes.Add(RegisterInMapRegistry(template, levelData));
+
+ // Bake last: it stamps LevelData.ScenePath from the ACTIVE scene, so the scene has to
+ // be saved (and therefore have a path) before this runs.
+ if (request.BakeImmediately)
+ {
+ notes.Add(LevelBakePipeline.Bake(authoring)
+ ? "Baked LevelData (see console for the bake report)."
+ : "Bake FAILED — see console. The scene and assets were still created.");
+ }
+
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+
+ Selection.activeGameObject = authoring.gameObject;
+ if (SceneView.lastActiveSceneView != null) SceneView.lastActiveSceneView.FrameSelected();
+
+ Debug.Log(
+ $"[MapPipeline] Created map '{request.MapName}' " +
+ $"({request.PlayerCount} player(s), {request.MapWidth}×{request.MapHeight} tiles, " +
+ $"band depth {layout.BandDepth}).\n" +
+ $" Scene: {scenePath}\n" +
+ $" LevelData: {dataPath}\n" +
+ string.Join("\n", notes.Where(n => !string.IsNullOrEmpty(n)).Select(n => " " + n)));
+
+ return true;
+ }
+
+ private static bool ValidatePreconditions(Request request, MapTemplate template,
+ out string error)
+ {
+ error = null;
+
+ if (string.IsNullOrWhiteSpace(request.MapName) || !ValidName.IsMatch(request.MapName))
+ {
+ error = "Map name must be letters, digits and underscores only — it becomes the " +
+ "scene file name and the string NGO uses to load the scene.";
+ return false;
+ }
+
+ if (template.matchServicesPrefab == null || template.matchNetworkPrefab == null)
+ {
+ error = "Core prefabs are missing. Open the 9Player scene and run " +
+ "TD → Map Pipeline → Build Core Prefabs From Open Scene first.";
+ return false;
+ }
+
+ string folder = template.SceneFolderPath;
+ if (string.IsNullOrEmpty(folder))
+ {
+ error = "MapTemplate has no output folder. Assign Scene Folder Asset on " +
+ MapTemplate.AssetPath + ".";
+ return false;
+ }
+
+ string scenePath = $"{folder}/{request.MapName}.unity";
+ if (System.IO.File.Exists(scenePath))
+ {
+ error = $"A scene already exists at '{scenePath}'. Pick a different name.";
+ return false;
+ }
+
+ string dataPath = $"{folder}/{request.MapName}.asset";
+ if (System.IO.File.Exists(dataPath))
+ {
+ error = $"A LevelData asset already exists at '{dataPath}'. Pick a different name.";
+ return false;
+ }
+
+ return true;
+ }
+
+ // -------------------------------------------------------------------
+ // Authoring hierarchy
+ // -------------------------------------------------------------------
+
+ private static LevelAuthoring BuildAuthoring(Request request, Layout layout,
+ LevelData levelData)
+ {
+ var rootGO = new GameObject("_LevelAuthoring");
+ var authoring = rootGO.AddComponent();
+
+ authoring.targetAsset = levelData;
+ authoring.mapName = request.MapName;
+ authoring.playerCount = request.PlayerCount;
+ authoring.expectedGoalCount = 1;
+ authoring.mapDescription = request.Description ?? "";
+ authoring.author = request.Author ?? "";
+ authoring.buildAccess = request.BuildAccess;
+
+ // Default every gizmo category on. A designer opening a fresh map wants to SEE the
+ // starter layout without hunting for toggles; turning them off is the deliberate act.
+ authoring.alwaysShowPlayerZones = true;
+ authoring.alwaysShowSpawners = true;
+ authoring.alwaysShowLeakExits = true;
+ authoring.alwaysShowGoals = true;
+ authoring.alwaysShowMapArea = true;
+
+ CreateVolume("MapArea", rootGO.transform, layout.MapArea);
+
+ var goal = CreateVolume("Goal", rootGO.transform, layout.Goal);
+ goal.GetComponent().placementValidity = PlacementValidity.Invalid;
+
+ for (int i = 0; i < request.PlayerCount; i++)
+ {
+ int playerNumber = i + 1;
+ var slot = (PlayerSlot)(byte)playerNumber;
+
+ var group = new GameObject($"Player {playerNumber}");
+ group.transform.SetParent(rootGO.transform, worldPositionStays: false);
+
+ var zone = CreateVolume(
+ $"Player{playerNumber}Zone", group.transform, layout.Zones[i]);
+ var zoneVolume = zone.GetComponent();
+ zoneVolume.owner = slot;
+ zoneVolume.placementValidity = PlacementValidity.Allowed;
+
+ var spawn = CreateVolume(
+ $"Player{playerNumber}Spawn", group.transform, layout.Spawners[i]);
+ var spawnVolume = spawn.GetComponent();
+ spawnVolume.owner = slot;
+ spawnVolume.spawnerIdInZone = 0;
+ spawnVolume.spawnFacing = Direction.North; // bands run south -> north
+ spawnVolume.placementValidity = PlacementValidity.Invalid;
+
+ // The northernmost band has no leak — it's the final defender, and its zone is
+ // goal-adjacent instead (bake rule P5-8).
+ if (i < layout.Leaks.Length)
+ {
+ var leak = CreateVolume(
+ $"Player{playerNumber}Leak", group.transform, layout.Leaks[i]);
+ var leakVolume = leak.GetComponent();
+ leakVolume.sourceZone = slot;
+ leakVolume.target = (PlayerSlot)(byte)(playerNumber + 1);
+ leakVolume.weight = 1f;
+ leakVolume.placementValidity = PlacementValidity.Invalid;
+ }
+ }
+
+ return authoring;
+ }
+
+ // Builds one authoring volume covering the given tile rectangle. Tiles are edge-aligned, so
+ // a rect spanning tiles [x0..x1] occupies world X [x0, x1+1] — which is exactly
+ // RectInt.xMin..RectInt.xMax. Geometry goes on the BoxCollider (centre zero, size = extent)
+ // with the transform at the volume's centre, matching the existing maps and keeping
+ // VolumeEditTool's edge-drag behaviour predictable.
+ private static GameObject CreateVolume(string name, Transform parent, RectInt tiles)
+ where T : VolumeBase
+ {
+ var go = new GameObject(name);
+ go.transform.SetParent(parent, worldPositionStays: false);
+ go.transform.localPosition = new Vector3(
+ (tiles.xMin + tiles.xMax) * 0.5f * GridCoordinates.TILE_SIZE,
+ 0f,
+ (tiles.yMin + tiles.yMax) * 0.5f * GridCoordinates.TILE_SIZE);
+
+ // Added before the volume component so VolumeBase's [RequireComponent] doesn't add a
+ // second, default-sized collider.
+ var collider = go.AddComponent();
+ collider.center = Vector3.zero;
+ collider.size = new Vector3(
+ tiles.width * GridCoordinates.TILE_SIZE,
+ VolumeHeight,
+ tiles.height * GridCoordinates.TILE_SIZE);
+
+ go.AddComponent();
+ return go;
+ }
+
+ // -------------------------------------------------------------------
+ // Terrain
+ // -------------------------------------------------------------------
+
+ private static void CreateTerrain(Request request, MapTemplate template)
+ {
+ int skirt = Mathf.Max(0, template.terrainSkirtTiles);
+ float carve = Mathf.Clamp(template.terrainCarveDepth, 0f, template.terrainHeight);
+
+ var data = new TerrainData { name = request.MapName + "_TerrainData" };
+ // Resolution before size: changing heightmapResolution resets size.
+ data.heightmapResolution = template.terrainHeightmapResolution;
+ data.size = new Vector3(
+ request.MapWidth + skirt * 2f,
+ Mathf.Max(1f, template.terrainHeight),
+ request.MapHeight + skirt * 2f);
+
+ if (template.terrainLayers != null && template.terrainLayers.Length > 0)
+ {
+ data.terrainLayers = template.terrainLayers;
+ }
+
+ // Start the surface partway up its own height range and drop the transform to match, so
+ // the flat ground lands on the buildable plane (Y=0) with room to carve downwards.
+ if (carve > 0f)
+ {
+ int res = data.heightmapResolution;
+ float normalized = carve / Mathf.Max(1f, template.terrainHeight);
+ var heights = new float[res, res];
+ for (int y = 0; y < res; y++)
+ {
+ for (int x = 0; x < res; x++) heights[y, x] = normalized;
+ }
+ data.SetHeights(0, 0, heights);
+ }
+
+ AssetDatabase.CreateAsset(
+ data, $"{template.SceneFolderPath}/{request.MapName}_TerrainData.asset");
+
+ var terrainGO = Terrain.CreateTerrainGameObject(data);
+ terrainGO.name = "Terrain";
+ terrainGO.transform.position = new Vector3(-skirt, -carve, -skirt);
+
+ int layer = LayerMask.NameToLayer(TerrainLayerName);
+ if (layer >= 0)
+ {
+ terrainGO.layer = layer;
+ }
+ else
+ {
+ Debug.LogWarning(
+ $"[MapPipeline] Layer '{TerrainLayerName}' does not exist, so the new terrain was " +
+ "left on Default. The builder's ground raycast and spell targeting both filter " +
+ "on that layer and will ignore this terrain until it's fixed.");
+ }
+
+ if (template.terrainMaterial != null)
+ {
+ terrainGO.GetComponent().materialTemplate = template.terrainMaterial;
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Wiring and registration
+ // -------------------------------------------------------------------
+
+ private static void WireLevelLoader(GameObject services, LevelData levelData)
+ {
+ var loader = services.GetComponentInChildren(true);
+ if (loader == null)
+ {
+ Debug.LogError("[MapPipeline] MatchServices prefab has no LevelLoader — the map " +
+ "will not load at runtime. Re-run Build Core Prefabs.");
+ return;
+ }
+
+ var so = new SerializedObject(loader);
+ var prop = so.FindProperty("level");
+ if (prop == null)
+ {
+ Debug.LogError("[MapPipeline] LevelLoader has no serialized field 'level'. It was " +
+ "renamed — update NewMapBuilder.");
+ return;
+ }
+ prop.objectReferenceValue = levelData;
+ so.ApplyModifiedPropertiesWithoutUndo();
+ }
+
+ private static string RegisterInBuildSettings(string scenePath)
+ {
+ var scenes = EditorBuildSettings.scenes.ToList();
+ if (scenes.Any(s => s.path == scenePath))
+ {
+ return "Already in Build Settings.";
+ }
+
+ scenes.Add(new EditorBuildSettingsScene(scenePath, true));
+ EditorBuildSettings.scenes = scenes.ToArray();
+ return $"Added to Build Settings (index {scenes.Count - 1}).";
+ }
+
+ // MapRegistry lives in the MainMenu scene, not the map scene — the one registration step
+ // that isn't visible from where the designer is working, and therefore the one most often
+ // forgotten. Open it additively, append, save, close.
+ private static string RegisterInMapRegistry(MapTemplate template, LevelData levelData)
+ {
+ string path = template.MainMenuScenePath;
+ if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
+ {
+ return $"SKIPPED MapRegistry — no scene at '{path}'. Assign Main Menu Scene on " +
+ $"{MapTemplate.AssetPath}, then add this LevelData to the registry by hand.";
+ }
+
+ Scene menu = default;
+ bool opened = false;
+ try
+ {
+ menu = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
+ opened = true;
+
+ MapRegistry registry = null;
+ foreach (var root in menu.GetRootGameObjects())
+ {
+ registry = root.GetComponentInChildren(true);
+ if (registry != null) break;
+ }
+
+ if (registry == null)
+ {
+ return $"SKIPPED MapRegistry — none found in '{menu.name}'. Add the LevelData by hand.";
+ }
+
+ var so = new SerializedObject(registry);
+ var maps = so.FindProperty("maps");
+ if (maps == null)
+ {
+ return "SKIPPED MapRegistry — serialized field 'maps' not found (renamed?).";
+ }
+
+ for (int i = 0; i < maps.arraySize; i++)
+ {
+ if (maps.GetArrayElementAtIndex(i).objectReferenceValue == levelData)
+ {
+ return "Already in MapRegistry.";
+ }
+ }
+
+ maps.InsertArrayElementAtIndex(maps.arraySize);
+ maps.GetArrayElementAtIndex(maps.arraySize - 1).objectReferenceValue = levelData;
+ so.ApplyModifiedPropertiesWithoutUndo();
+
+ EditorSceneManager.MarkSceneDirty(menu);
+ EditorSceneManager.SaveScene(menu);
+ return $"Added to MapRegistry in '{menu.name}' (slot {maps.arraySize - 1}).";
+ }
+ finally
+ {
+ if (opened && menu.IsValid())
+ {
+ EditorSceneManager.CloseScene(menu, removeScene: true);
+ }
+ }
+ }
+ }
+}
diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta
new file mode 100644
index 0000000..e60c9fd
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/NewMapBuilder.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 5eda54745c5c78c489eb2cf9aa6265b7
\ No newline at end of file
diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs
new file mode 100644
index 0000000..b1e07ba
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs
@@ -0,0 +1,205 @@
+// Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs
+using UnityEditor;
+using UnityEngine;
+
+using TD.Core;
+
+namespace TD.Levels.Editor
+{
+ ///
+ /// The TD/New Map… dialog. Collects the handful of decisions only a designer can make,
+ /// validates the resulting layout live, and hands off to .
+ ///
+ public class NewMapWindow : EditorWindow
+ {
+ // Mirrors LevelBakePipeline's accepted set — anything else is a hard bake error (P2-15),
+ // so there's no point offering it here.
+ private static readonly int[] PlayerCountValues = { 1, 2, 3, 4, 5, 9 };
+ private static readonly string[] PlayerCountLabels =
+ { "1 player", "2 players", "3 players", "4 players", "5 players", "9 players" };
+
+ private const string AuthorPrefKey = "TD.MapPipeline.LastAuthor";
+
+ private readonly NewMapBuilder.Request request = new NewMapBuilder.Request();
+ private bool initialized;
+ private Vector2 scroll;
+
+ [MenuItem("TD/New Map...", false, 100)]
+ public static void Open()
+ {
+ var window = GetWindow(utility: true, title: "New Map", focus: true);
+ window.minSize = new Vector2(420f, 460f);
+ window.Show();
+ }
+
+ private void Initialize()
+ {
+ if (initialized) return;
+ initialized = true;
+
+ var template = MapTemplate.LoadOrCreate();
+ request.MapWidth = template.defaultMapWidth;
+ request.MapHeight = template.defaultMapHeight;
+ request.Author = EditorPrefs.GetString(AuthorPrefKey, "");
+ }
+
+ private void OnGUI()
+ {
+ Initialize();
+ var template = MapTemplate.LoadOrCreate();
+
+ scroll = EditorGUILayout.BeginScrollView(scroll);
+
+ bool prefabsReady = template.matchServicesPrefab != null
+ && template.matchNetworkPrefab != null;
+ if (!prefabsReady)
+ {
+ EditorGUILayout.HelpBox(
+ "Core prefabs haven't been built yet.\n\n" +
+ "Open the 9Player scene, then run:\n" +
+ "TD → Map Pipeline → Build Core Prefabs From Open Scene",
+ MessageType.Error);
+ EditorGUILayout.Space(6);
+ }
+
+ EditorGUILayout.LabelField("Identity", EditorStyles.boldLabel);
+ request.MapName = EditorGUILayout.TextField(
+ new GUIContent("Map Name",
+ "Becomes the scene file name, the LevelData asset name, and the string NGO " +
+ "uses to load the scene. Letters, digits and underscores only."),
+ request.MapName);
+ request.Author = EditorGUILayout.TextField("Author", request.Author);
+
+ EditorGUILayout.LabelField(new GUIContent("Description",
+ "Shown in the lobby's map browser. Empty produces a bake warning."));
+ request.Description = EditorGUILayout.TextArea(
+ request.Description, GUILayout.Height(38f));
+
+ EditorGUILayout.Space(8);
+ EditorGUILayout.LabelField("Shape", EditorStyles.boldLabel);
+ request.PlayerCount = EditorGUILayout.IntPopup(
+ "Players", request.PlayerCount, PlayerCountLabels, PlayerCountValues);
+ request.MapWidth = Mathf.Max(8, EditorGUILayout.IntField(
+ new GUIContent("Width (tiles)", "1 tile = 1 world unit."), request.MapWidth));
+ request.MapHeight = Mathf.Max(8, EditorGUILayout.IntField(
+ new GUIContent("Height (tiles)", "1 tile = 1 world unit."), request.MapHeight));
+
+ request.BuildAccess = (BuildAccess)EditorGUILayout.EnumPopup(
+ new GUIContent("Build Access",
+ "OwnerOnly: each player builds only in their own zone.\n" +
+ "Shared: everyone builds anywhere on the map's buildable area.\n\n" +
+ "Changeable later on _LevelAuthoring — it just needs a re-bake."),
+ request.BuildAccess);
+
+ if (request.BuildAccess == BuildAccess.Shared)
+ {
+ EditorGUILayout.HelpBox(
+ "Shared: every band forms one cooperative maze. Zones still define " +
+ "territory for leak attribution, camera start and builder spawn. Towers stay " +
+ "owned by whoever paid — only that player can sell or upgrade them.",
+ MessageType.None);
+ }
+
+ EditorGUILayout.Space(8);
+ EditorGUILayout.LabelField("On Create", EditorStyles.boldLabel);
+ request.CreateTerrain = EditorGUILayout.Toggle(
+ new GUIContent("Create Terrain",
+ "Adds a Terrain sized to the map plus a skirt, on the TerrainGeometry layer, " +
+ "flattened onto the buildable plane."),
+ request.CreateTerrain);
+ request.AddToBuildSettings = EditorGUILayout.Toggle(
+ new GUIContent("Add to Build Settings",
+ "Required — NGO cannot load a scene that isn't in the build list."),
+ request.AddToBuildSettings);
+ request.AddToMapRegistry = EditorGUILayout.Toggle(
+ new GUIContent("Add to MapRegistry",
+ "Opens the MainMenu scene, appends the LevelData to the lobby's map browser, " +
+ "and saves it."),
+ request.AddToMapRegistry);
+ request.BakeImmediately = EditorGUILayout.Toggle(
+ new GUIContent("Bake immediately",
+ "Runs the bake on the generated starter layout so the map is valid and " +
+ "playable the moment it's created."),
+ request.BakeImmediately);
+
+ // Registry wiring is the one step that reaches into a scene the designer isn't looking
+ // at, so a broken reference should be visible BEFORE Create, not in the summary after.
+ if (request.AddToMapRegistry && !System.IO.File.Exists(template.MainMenuScenePath))
+ {
+ EditorGUILayout.HelpBox(
+ "Main Menu Scene isn't resolving, so the new map won't be added to the lobby's " +
+ "map browser. Assign it on MapTemplate, or add the LevelData to MapRegistry.Maps " +
+ "by hand afterwards.",
+ MessageType.Warning);
+ }
+
+ EditorGUILayout.Space(8);
+ DrawLayoutPreview(template);
+
+ EditorGUILayout.EndScrollView();
+
+ EditorGUILayout.Space(6);
+ bool canCreate = prefabsReady &&
+ NewMapBuilder.TryComputeLayout(
+ template, request.MapWidth, request.MapHeight,
+ request.PlayerCount, request.BuildAccess, out _, out _);
+
+ using (new EditorGUI.DisabledScope(!canCreate))
+ {
+ if (GUILayout.Button("Create Map", GUILayout.Height(30f)))
+ {
+ CreateMap();
+ }
+ }
+ }
+
+ private void DrawLayoutPreview(MapTemplate template)
+ {
+ EditorGUILayout.LabelField("Starter Layout", EditorStyles.boldLabel);
+
+ if (!NewMapBuilder.TryComputeLayout(template, request.MapWidth, request.MapHeight,
+ request.PlayerCount, request.BuildAccess,
+ out var layout, out string error))
+ {
+ EditorGUILayout.HelpBox(error, MessageType.Error);
+ return;
+ }
+
+ string routing = layout.Leaks.Length > 0
+ ? $"through {layout.Leaks.Length} one-tile leak gate(s) " +
+ $"{Mathf.Min(template.leakGateWidth, layout.Zones[0].width)} tiles wide"
+ : "across directly-adjacent band borders (no leak gates)";
+
+ EditorGUILayout.HelpBox(
+ $"{request.PlayerCount} full-width band(s), {layout.BandDepth} tiles deep each, " +
+ $"stacked south to north.\n" +
+ $"Each band gets a spawner at its south edge; enemies travel north " +
+ $"{routing} to the goal.\n\n" +
+ $"Grid will bake to {layout.MapArea.width}×{layout.MapArea.height} with its " +
+ $"south-west corner at tile (0, 0).",
+ MessageType.Info);
+
+ EditorGUILayout.LabelField(
+ "Tune the starter proportions on the MapTemplate asset:",
+ EditorStyles.miniLabel);
+ if (GUILayout.Button("Select MapTemplate", EditorStyles.miniButton))
+ {
+ Selection.activeObject = template;
+ EditorGUIUtility.PingObject(template);
+ }
+ }
+
+ private void CreateMap()
+ {
+ EditorPrefs.SetString(AuthorPrefKey, request.Author ?? "");
+
+ if (NewMapBuilder.Create(request, out string error))
+ {
+ Close();
+ return;
+ }
+
+ EditorUtility.DisplayDialog("Could not create map", error, "OK");
+ }
+ }
+}
diff --git a/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta
new file mode 100644
index 0000000..850067e
--- /dev/null
+++ b/Assets/_Project/Scripts/Editor/Levels/NewMapWindow.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 50a9cf35b1b63204da8774b8afe7003e
\ No newline at end of file
diff --git a/Assets/_Project/Scripts/Gameplay/LevelLoader.cs b/Assets/_Project/Scripts/Gameplay/LevelLoader.cs
index 3a29dfb..b93427f 100644
--- a/Assets/_Project/Scripts/Gameplay/LevelLoader.cs
+++ b/Assets/_Project/Scripts/Gameplay/LevelLoader.cs
@@ -355,6 +355,39 @@ namespace TD.Gameplay
return level.OwnerGrid[idx];
}
+ ///
+ /// This map's build-permission rule. for an unloaded
+ /// or unbaked level, which is the safe default (it can only ever reject more).
+ ///
+ public BuildAccess BuildAccess => level != null ? level.BuildAccess : BuildAccess.OwnerOnly;
+
+ ///
+ /// True if is permitted to build on under
+ /// this map's rule.
+ ///
+ ///
+ /// Permission ONLY — the caller still has to check and
+ /// . Keeping them separate is deliberate: each produces a different
+ /// PlacementRejectionReason, and collapsing them would cost the player a useful
+ /// message.
+ ///
+ /// Both the client's ghost preview and the server's authoritative check call this, so
+ /// they cannot drift apart and show a white ghost that then gets rejected.
+ ///
+ /// Under the tile must still belong to SOME player
+ /// zone. In practice every Buildable tile does, but stating it here keeps the method
+ /// meaningful on its own rather than relying on a caller's later check.
+ ///
+ public bool HasBuildPermission(Vector2Int tile, PlayerSlot slot)
+ {
+ if (slot == PlayerSlot.None) return false;
+
+ PlayerSlot owner = GetOwner(tile); // PlayerSlot.None when out of bounds
+ return BuildAccess == BuildAccess.Shared
+ ? owner != PlayerSlot.None
+ : owner == slot;
+ }
+
///
/// True if is currently occupied by a placed tower footprint.
/// Returns false for out-of-bounds tiles. Unlike , this grid
diff --git a/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs b/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs
index 9b1db7c..8800175 100644
--- a/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs
+++ b/Assets/_Project/Scripts/Gameplay/TowerPlacementController.cs
@@ -353,7 +353,7 @@ namespace TD.Gameplay
foreach (var tile in GridCoordinates.GetFootprintTiles(anchor, def.FootprintSize))
{
- if (loader.GetOwner(tile) != localSlot) return false;
+ if (!loader.HasBuildPermission(tile, localSlot)) return false;
if (loader.GetPlacement(tile) != PlacementState.Buildable) return false;
if (loader.IsOccupied(tile)) return false;
}
diff --git a/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs b/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs
index 3706dfb..24dacba 100644
--- a/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs
+++ b/Assets/_Project/Scripts/Gameplay/TowerPlacementManager.cs
@@ -217,8 +217,10 @@ namespace TD.Gameplay
footprint.Add(tile);
// ------------------------------------------------------------------
- // Check 1: Ownership
- // Every footprint tile must be owned by the placing player's zone.
+ // Check 1: Build permission
+ // On an OwnerOnly map every footprint tile must be owned by the placing
+ // player's zone; on a Shared map any zone's tile will do. LevelLoader owns
+ // that rule so the client's ghost preview can't disagree with us.
// ------------------------------------------------------------------
PlayerSlot placingSlot = ClientIdToPlayerSlot(req.SenderClientId);
if (placingSlot == PlayerSlot.None)
@@ -229,7 +231,7 @@ namespace TD.Gameplay
foreach (var tile in footprint)
{
- if (loader.GetOwner(tile) != placingSlot)
+ if (!loader.HasBuildPermission(tile, placingSlot))
{
Reject(req, PlacementRejectionReason.WrongOwner);
return;
@@ -533,37 +535,67 @@ namespace TD.Gameplay
// ----- Path-validity BFS ------------------------------------------
///
- /// Returns true if every spawner in 's zone can still
- /// reach an exit tile (any leak exit tile OR any goal tile) via walkable tiles,
- /// given the current state of LevelLoader's runtime walkability grid.
+ /// Returns true if the map's mazes are still solvable with the candidate footprint in
+ /// place — every spawner can still reach an exit tile (any leak exit from its own zone,
+ /// OR any goal tile) via walkable tiles, given LevelLoader's runtime grid.
///
///
- /// Mirrors bake-time P5-4. Runs a BFS per spawner against the runtime walkability
- /// grid. Reuses and scratch
- /// collections (cleared between BFS runs) to avoid GC allocation per call.
+ /// Mirrors bake-time P5-4. Reuses and
+ /// scratch collections (cleared between BFS runs) to avoid GC allocation per call.
+ ///
+ /// Scope depends on the map's build rule. Under
+ /// a player can only build inside their own zone, so
+ /// their footprint can only ever strand their OWN spawners — checking
+ /// 's zone alone is both sufficient and cheapest. Under
+ /// anyone can wall off anyone's lane, so every zone has to
+ /// be checked or a player could strand a teammate's spawner and leave its enemies with no
+ /// route at all.
///
- private bool CheckPathValidity(LevelLoader loader, PlayerSlot slot,
+ private bool CheckPathValidity(LevelLoader loader, PlayerSlot placingSlot,
HashSet virtualBlocked = null)
{
var levelData = loader.LevelData;
+ if (levelData?.PlayerZones == null) return true;
+
+ if (loader.BuildAccess == BuildAccess.Shared)
+ {
+ foreach (var zone in levelData.PlayerZones)
+ {
+ if (!ZoneSpawnersCanReachExit(loader, levelData, zone, virtualBlocked))
+ return false;
+ }
+ return true;
+ }
- // Find the PlayerZoneData for this slot.
- PlayerZoneData zoneData = null;
foreach (var zone in levelData.PlayerZones)
{
- if (zone.Owner == slot) { zoneData = zone; break; }
+ if (zone.Owner == placingSlot)
+ return ZoneSpawnersCanReachExit(loader, levelData, zone, virtualBlocked);
}
- if (zoneData == null || zoneData.Spawners == null || zoneData.Spawners.Length == 0)
+
+ // Placing player has no zone — nothing of theirs to strand.
+ return true;
+ }
+
+ ///
+ /// Runs the reachability BFS for every spawner in one zone. Returns true if they can all
+ /// still reach an exit (or the zone has no spawners to strand).
+ ///
+ private bool ZoneSpawnersCanReachExit(LevelLoader loader, LevelData levelData,
+ PlayerZoneData zoneData,
+ HashSet virtualBlocked)
+ {
+ if (zoneData?.Spawners == null || zoneData.Spawners.Length == 0)
{
// No spawners means nothing to block — treat as valid.
return true;
}
- // Build the exit tile set: union of all leak exit tiles and all goal tiles.
- var exitTiles = BuildExitTileSet(levelData, slot);
+ // Build the exit tile set: this zone's leak exits, plus all goal tiles.
+ var exitTiles = BuildExitTileSet(levelData, zoneData.Owner);
if (exitTiles.Count == 0)
{
- Debug.LogWarning($"[TowerPlacementManager] Zone {slot} has no exit tiles. " +
+ Debug.LogWarning($"[TowerPlacementManager] Zone {zoneData.Owner} has no exit tiles. " +
$"This should have been caught at bake time (P5-8).");
return true;
}
diff --git a/Assets/_Project/Settings/MapTemplate.asset b/Assets/_Project/Settings/MapTemplate.asset
new file mode 100644
index 0000000..a82dd59
--- /dev/null
+++ b/Assets/_Project/Settings/MapTemplate.asset
@@ -0,0 +1,39 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fb7355881928ea146a26471078f207c2, type: 3}
+ m_Name: MapTemplate
+ m_EditorClassIdentifier: Assembly-CSharp-Editor::TD.Levels.Editor.MapTemplate
+ matchServicesPrefab: {fileID: 1445952844252628864, guid: 13be8328f6275e14da787f25c94683ee, type: 3}
+ matchNetworkPrefab: {fileID: 8429081419068942390, guid: 7116de1968afffb4990ee24f709612fb, type: 3}
+ sceneFolderAsset: {fileID: 102900000, guid: 1ac41b242a484844a85bb02ca1ae9f1f, type: 3}
+ mainMenuScene: {fileID: 102900000, guid: 1f4cb4a6391f5e94285960890282b70e, type: 3}
+ sceneFolder: Assets/_Project/Scenes/Levels
+ mainMenuScenePath: Assets/_Project/Scenes/UI_Scenes/MainMenu.unity
+ terrainMaterial: {fileID: 2100000, guid: 594ea882c5a793440b60ff72d896021e, type: 2}
+ terrainLayers:
+ - {fileID: 8574412962073106934, guid: f72a840f9f0991747a2d10c3c220bd27, type: 2}
+ - {fileID: 8574412962073106934, guid: 445b935ebf050f74a96e491cb1596964, type: 2}
+ - {fileID: 8574412962073106934, guid: faa5ef4eade0336408d27e4e78ebf1a6, type: 2}
+ - {fileID: 8574412962073106934, guid: 79a46a4f0f2c8a04a9f50c26dc17dc48, type: 2}
+ terrainHeightmapResolution: 513
+ terrainHeight: 60
+ terrainSkirtTiles: 20
+ terrainCarveDepth: 5
+ defaultMapWidth: 100
+ defaultMapHeight: 100
+ playAreaMargin: 4
+ goalDepth: 5
+ goalWidth: 10
+ spawnerDepth: 5
+ spawnerWidth: 10
+ leakGateWidth: 8
+ minBandDepth: 8
diff --git a/Assets/_Project/Settings/MapTemplate.asset.meta b/Assets/_Project/Settings/MapTemplate.asset.meta
new file mode 100644
index 0000000..f79b9ea
--- /dev/null
+++ b/Assets/_Project/Settings/MapTemplate.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ac495796f7ea6a9478aa5512f162d264
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Docs/Map_Pipeline.md b/Docs/Map_Pipeline.md
new file mode 100644
index 0000000..c1e16ea
--- /dev/null
+++ b/Docs/Map_Pipeline.md
@@ -0,0 +1,188 @@
+# Map Pipeline
+
+How to make a new map, and what the generator puts in the scene for you.
+
+---
+
+## One-time setup
+
+Open **`9Player`** and run **`TD → Map Pipeline → Build Core Prefabs From Open Scene`**.
+
+This reads the fully-wired reference scene and writes:
+
+| Output | What it holds |
+|---|---|
+| `Assets/_Project/Prefabs/MatchCore/MatchServices.prefab` | Every map-independent, non-networked service |
+| `Assets/_Project/Prefabs/MatchCore/MatchNetwork.prefab` | The six scene-placed `NetworkBehaviour`s |
+| `Assets/_Project/Settings/MapTemplate.asset` | Prefab references, terrain defaults, starter-layout proportions |
+
+It **copies live components** rather than rebuilding them from an asset scan. `AssetDatabase.FindAssets`
+order isn't guaranteed stable across machines or re-imports, and several of these arrays double as
+network identity — `EnemyUpgradePool.options` indices *are* card network ids, and
+`TowerPlacementManager.towerDefinitions` indices *are* `TowerTypeId`. Two people generating the same
+map could commit different orders, and *that* desyncs a host from a client. Copying sidesteps it, and
+gives each new map the same known-good content as the reference.
+
+> Maps having **different** catalogs from each other is fine and supported — every peer loads the same
+> scene, and `PlayerTowerDeck.ServerInitialize` clears the deck at match start. Per-map enemy rosters
+> are a matter of assigning a different `RunDefinition` on `_MatchNetwork/RunState`.
+
+> The reference scene's contents aren't modified, but Unity marks it dirty. **Don't save it.**
+
+Re-run this any time the shared boilerplate changes in a way the prefab should pick up.
+
+---
+
+## Making a map
+
+**`TD → New Map...`**
+
+Fill in name, player count, and size. The dialog validates the starter layout live and tells you the
+exact width or height to use if the shape can't hold one.
+
+On Create it does all of this:
+
+1. Creates and saves the scene in `Assets/_Project/Scenes/Levels/`
+2. Instantiates `_MatchServices` (**linked** prefab instance) and `_MatchNetwork` (**unpacked**)
+3. Creates the `LevelData` asset and assigns it to **both** `LevelAuthoring.targetAsset` *and*
+ `LevelLoader.level`
+4. Generates a bakeable starter volume layout
+5. Creates a `Terrain` on the `TerrainGeometry` layer, sized to the map plus a skirt
+6. Registers the scene in **Build Settings**
+7. Appends the `LevelData` to the **`MapRegistry`** in `MainMenu.unity`
+8. Runs the bake
+
+Steps 3, 6 and 7 are the ones that used to fail silently — a map missing any of them looks fine in
+the editor and breaks only at match start, or just never appears in the lobby.
+
+A generated map bakes with **zero warnings** as long as you filled in author and description.
+
+---
+
+## What you get, and where to edit it
+
+Four roots instead of the ~30 the hand-authored maps carry:
+
+```
+_LevelAuthoring ← yours: shape the volumes here
+_MatchServices ← shared prefab: don't edit per-map (except LevelLoader.level)
+_MatchNetwork ← the six NetworkBehaviours, unpacked
+Terrain ← yours: sculpt here
+```
+
+`_MatchServices` is a **linked prefab instance**, so fixing something in
+`MatchServices.prefab` fixes it in every map at once. The one field that is legitimately a
+per-instance override is `LevelLoader.level`.
+
+**Never press "Apply All" on the `_MatchServices` instance** — that would push this map's
+`LevelData` into the shared prefab.
+
+`_MatchNetwork` is unpacked deliberately: NGO treats in-scene placed `NetworkObject`s that are prefab
+instances differently from loose ones, and unpacking keeps generated scenes structurally identical to
+hand-authored ones. The cost is that changes to `MatchNetwork.prefab` don't propagate to maps already
+created — there are only three asset references in it (`RunDefinition`, `GoldConfig`,
+`EnemyScalingConfig`), so fix those by hand if they ever change.
+
+---
+
+## The starter layout
+
+Player bands stacked south → north, full map width:
+
+```
+ ┌─────────── Goal ───────────┐ north
+ │ Player N band │
+ │ ····· leak gate ····· │
+ │ Player N-1 band │
+ │ ····· leak gate ····· │
+ │ Player 1 band │
+ │ [Player 1 spawner] │ south
+ └── MapArea (margin border) ─┘
+```
+
+Enemies spawn at the south edge of their owner's band and walk north. Each band leaks through a
+one-tile gate into the next; the northernmost band is goal-adjacent instead of having a leak.
+
+Proportions (margin, band depth, gate width, goal size, terrain skirt and carve depth) all live on
+**`MapTemplate.asset`** — tune them there, not in code.
+
+---
+
+## Build Access: one maze each, or one maze together
+
+`_LevelAuthoring → Rules → Build Access` is a per-map choice. Also offered in the New Map dialog.
+
+| Mode | Meaning |
+|---|---|
+| `OwnerOnly` | Default. A player builds only inside their own `PlayerZoneVolume`. |
+| `Shared` | Any player builds on any Buildable tile — the whole map is one cooperative maze. |
+
+**Ownership doesn't disappear in Shared mode.** `OwnerGrid` still drives leak attribution, camera
+start position, builder spawn point, and minimap tinting; zones still own their spawners and leak
+exits. The only thing that lifts is the placement restriction. That's why this is a per-map enum and
+not a change to how maps are authored — a Shared map is authored exactly like an OwnerOnly one.
+
+**Towers still belong to whoever paid.** Sell, upgrade and paint stay owner-gated in both modes, so a
+teammate can't sell your tower out of the lane you put it in.
+
+Both modes route through `LevelLoader.HasBuildPermission`, which the client's ghost preview and the
+server's authoritative check both call — they can't drift apart and show a white ghost that then gets
+rejected.
+
+> **Shared mode widens path validation.** Under `OwnerOnly` a player can only strand their own
+> spawners, so `TowerPlacementManager.CheckPathValidity` checks one zone. Under `Shared` anyone can
+> wall off anyone's lane, so it checks *every* zone's spawners — otherwise a player could leave a
+> teammate's enemies with no route to any exit. Cost is one BFS per spawner per placement attempt
+> rather than one per placement; placements are already throttled to `requestsPerFrame`.
+
+Changing the mode on an existing map just needs a re-bake.
+
+### Leak exits are optional on Shared maps
+
+Bake rule **P5-8** ("every zone must have an outgoing leak or be goal-adjacent") is **skipped on
+Shared maps**, so you can delete the `LeakExitVolume`s entirely. Every other leak rule is conditional
+on a leak existing, so they're vacuously satisfied at zero.
+
+That's safe because leak exits do almost nothing at runtime. `PathfindingService.ComputePath` takes no
+destination — enemies always path to `LevelData.Goals`, and the route through a gate is *emergent*
+from walkability, never directed. `LeakExitData.NormalizedWeight` is written by the bake and read
+nowhere. Leak *attribution* runs off `OwnerGrid`, not leak volumes, so it keeps working. The safety
+property P5-8 protected is enforced more strictly by **P5-4**, which BFSes every spawner to the exit
+set — and with no leaks present that set is the goal tiles, which is exactly the right requirement.
+
+> **Zones must then be directly adjacent.** A `LeakExitVolume`'s tiles are walkable; a bare gap
+> between two zones is not. Delete the leaks without closing the gap and the bands become
+> disconnected — P5-4 hard-errors and P5-11 warns, so the bake catches it loudly rather than shipping
+> a map whose enemies can't move.
+
+New Map handles this for you: choosing **Shared** generates bands butted directly together with no
+gate rows and no leak volumes. Choosing **OwnerOnly** generates the one-tile gates.
+
+---
+
+## Changing the Quick Play map
+
+Quick Start skips the lobby and loads **`MapRegistry.Default`**, which is the *first valid entry* in
+the `Maps` array — not a separate setting.
+
+Open `MainMenu`, select the `MapRegistry` GameObject, and drag the map you want to element **0**.
+Entries with an empty `MapName` or `ScenePath` are skipped, so "first" means first *usable*.
+
+New maps are **appended** to the array, so creating one never silently changes what Quick Play loads.
+Reordering is deliberate.
+
+---
+
+## Things worth knowing
+
+- **Walkability is the union of the gameplay volumes**, not something you paint. Walls are the
+ *absence* of a `PlayerZone` / `Spawner` / `LeakExit` / `Goal` volume. `MapAreaVolume` tiles are
+ deliberately **not** walkable — that volume only bounds camera pan and builder movement.
+- **Terrain must stay on the `TerrainGeometry` layer.** The builder's ground raycast and spell
+ targeting both filter on it; on `Default` the builder silently walks at Y=0.
+- **Terrain visuals have no relationship to the grid.** Nothing validates that the hills you sculpt
+ match the volumes you placed. That correspondence is yours to keep.
+- **Volumes must be axis-aligned and unit-scaled.** Rotation is a hard bake error; non-unit
+ `Transform.Scale` is a warning. Size volumes with `BoxCollider.Size`, or use the
+ **Resize Volume Edge** scene tool.
+- `MatchRules.MaxPlayers` is **3**. Larger player counts bake fine but no lobby can fill them yet.
diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset
index 789ebb2..ebac9f7 100644
--- a/ProjectSettings/EditorBuildSettings.asset
+++ b/ProjectSettings/EditorBuildSettings.asset
@@ -6,10 +6,10 @@ EditorBuildSettings:
serializedVersion: 2
m_Scenes:
- enabled: 1
- path: Assets/_Project/Scenes/UI/MainMenu.unity
+ path: Assets/_Project/Scenes/UI_Scenes/MainMenu.unity
guid: 1f4cb4a6391f5e94285960890282b70e
- enabled: 1
- path: Assets/_Project/Scenes/UI/Lobby.unity
+ path: Assets/_Project/Scenes/UI_Scenes/Lobby.unity
guid: 3a3639dca674a8049a570cb848bb69d2
- enabled: 1
path: Assets/_Project/Scenes/Levels/Main.unity
@@ -17,5 +17,8 @@ EditorBuildSettings:
- enabled: 1
path: Assets/_Project/Scenes/Levels/9Player.unity
guid: 74fdeec477e257d4484b38108c283d84
+ - enabled: 1
+ path: Assets/_Project/Scenes/Levels/3Player.unity
+ guid: 128de09101c3e3240b094d29d1eb9d22
m_configObjects:
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}