diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs
index ff89be3..d7c37dc 100644
--- a/GamecraftModdingAPI/Block.cs
+++ b/GamecraftModdingAPI/Block.cs
@@ -32,6 +32,11 @@ namespace GamecraftModdingAPI
/// Place a new block at the given position. If scaled, position means the center of the block. The default block size is 0.2 in terms of position.
/// Place blocks next to each other to connect them.
/// The placed block will be a complete block with a placement grid and collision which will be saved along with the game.
+ ///
+ /// When placing multiple blocks, do not access properties immediately after creation as this
+ /// triggers a sync each time which can affect performance and may cause issues with the game.
+ /// You may either use AsyncUtils.WaitForSubmission() after placing all of the blocks
+ /// or simply access the block properties which will trigger the synchronization the first time a property is used.
///
/// The block's type
/// The block's color
@@ -60,7 +65,9 @@ namespace GamecraftModdingAPI
/// Place blocks next to each other to connect them.
/// The placed block will be a complete block with a placement grid and collision which will be saved along with the game.
///
- /// This method waits for the block to be constructed in the game.
+ /// This method waits for the block to be constructed in the game which may take a significant amount of time.
+ /// Only use this to place a single block.
+ /// For placing multiple blocks, use PlaceNew() then AsyncUtils.WaitForSubmission() when done with placing blocks.
///
/// The block's type
/// The block's color
@@ -107,11 +114,11 @@ namespace GamecraftModdingAPI
Id = id;
if (!BlockEngine.BlockExists(Id))
{
- Sync();
+ /*Sync();
if (!BlockEngine.BlockExists(Id))
{
throw new BlockDoesNotExistException($"Block {Id.entityID} must be placed using PlaceNew(...) since it does not exist yet");
- }
+ }*/
}
}
@@ -119,17 +126,6 @@ namespace GamecraftModdingAPI
{
}
- ///
- /// Synchronize newly created entity components with entities DB.
- /// This forces a partial game tick, so it may be slow.
- /// This also has the potential to make Gamecraft unstable.
- /// Use this sparingly.
- ///
- protected static void Sync()
- {
- DeterministicStepCompositionRootPatch.SubmitEntitiesNow();
- }
-
public EGID Id { get; protected set; }
///
@@ -159,6 +155,7 @@ namespace GamecraftModdingAPI
///
/// The block's non-uniform scale or zero if the block's invalid. Independent of the uniform scaling.
+ /// The default scale of 1 means 0.2 in terms of position.
///
public float3 Scale
{
@@ -171,6 +168,7 @@ namespace GamecraftModdingAPI
///
/// The block's uniform scale or zero if the block's invalid. Also sets the non-uniform scale.
+ /// The default scale of 1 means 0.2 in terms of position.
///
public int UniformScale
{
diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs
index eb462f9..6b412a7 100644
--- a/GamecraftModdingAPI/Blocks/BlockEngine.cs
+++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs
@@ -10,6 +10,7 @@ using Svelto.DataStructures;
using Svelto.ECS;
using GamecraftModdingAPI.Engines;
+using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Blocks
{
@@ -24,6 +25,8 @@ namespace GamecraftModdingAPI.Blocks
public bool isRemovable => false;
+ internal bool Synced = true;
+
public void Dispose()
{
}
@@ -60,6 +63,11 @@ namespace GamecraftModdingAPI.Blocks
/// An editable reference to the struct
public ref T GetBlockInfo(EGID blockID) where T : struct, IEntityComponent
{
+ if (!Synced)
+ {
+ Sync();
+ Synced = true;
+ }
if (entitiesDB.Exists(blockID))
return ref entitiesDB.QueryEntity(blockID);
T[] structHolder = new T[1]; //Create something that can be referenced
@@ -76,11 +84,15 @@ namespace GamecraftModdingAPI.Blocks
/// An editable reference to the struct
public ref T GetBlockInfo(EGID blockID, out bool exists) where T : struct, IEntityComponent
{
+ if (!Synced)
+ {
+ Sync();
+ Synced = true;
+ }
exists = entitiesDB.Exists(blockID);
if (exists)
return ref entitiesDB.QueryEntity(blockID);
T[] structHolder = new T[1];
- //ref T defRef = ref structHolder[0];
return ref structHolder[0];
}
@@ -142,6 +154,17 @@ namespace GamecraftModdingAPI.Blocks
return list.ToArray();
}
+ ///
+ /// Synchronize newly created entity components with entities DB.
+ /// This forces a partial game tick, so it may be slow.
+ /// This also has the potential to make Gamecraft unstable.
+ /// Use this sparingly.
+ ///
+ private static void Sync()
+ {
+ DeterministicStepCompositionRootPatch.SubmitEntitiesNow();
+ }
+
#if DEBUG
public EntitiesDB GetEntitiesDB()
{
diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs
index 28642e8..35f0a92 100644
--- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs
+++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs
@@ -24,7 +24,7 @@ namespace GamecraftModdingAPI.Blocks
///
public class PlacementEngine : IApiEngine
{
- public bool IsInGame = false;
+ public bool IsInGame;
public void Dispose()
{
@@ -119,6 +119,7 @@ namespace GamecraftModdingAPI.Blocks
ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID);
pickedBlock.placedBlockEntityID = playerEGID;
pickedBlock.placedBlockWasAPickedBlock = false;
+ Block.BlockEngine.Synced = false; // Block entities will need to be submitted before properties can be used
return newBlockID;
}
@@ -126,7 +127,7 @@ namespace GamecraftModdingAPI.Blocks
public bool isRemovable => false;
- [HarmonyPatch]
+ [HarmonyPatch]
public class FactoryObtainerPatch
{
static void Postfix(BlockEntityFactory blockEntityFactory)
diff --git a/GamecraftModdingAPI/Utility/AsyncUtils.cs b/GamecraftModdingAPI/Utility/AsyncUtils.cs
index fcb5878..c646f8f 100644
--- a/GamecraftModdingAPI/Utility/AsyncUtils.cs
+++ b/GamecraftModdingAPI/Utility/AsyncUtils.cs
@@ -10,6 +10,7 @@ namespace GamecraftModdingAPI.Utility
///
/// Waits for entity submission asynchronously.
+ /// Use after placing a block or otherwise creating things in the game to access their properties.
///
public static async Task WaitForSubmission()
{