Set up DOTS + Netcode for Entities foundation

One-time stack setup per Docs/dots-setup-task.md (Unity 6.4.7 / 6000.4.7f1).
Packages: entities 6.4.0, entities.graphics 6.4.0, netcode 1.13.2, physics 1.4.6.

- Assets/_Project asmdef split: ProjectM.Simulation/Client/Server/Authoring (root ns ProjectM)
- GameBootstrap : ClientServerBootstrap; verified separate client + server worlds in Play Mode
- Gameplay subscene wired into SampleScene as a baking target
- Heartbeat component + Burst ISystem; EditMode smoke test green (1/1)
- In-repo Obsidian vault (Docs/Vault) incl. DR-001 (plain-Entities test over internal NetCodeTestWorld)
- Portable .mcp.json (basic-memory + serena via ${CLAUDE_PROJECT_DIR}); CLAUDE.md conventions
- .gitignore for DOTS baking cache + machine-local config

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Luis Gonzalez
2026-05-29 22:06:44 -07:00
parent 25e3493e75
commit 99d8d2d2a9
74 changed files with 1609 additions and 36 deletions
@@ -0,0 +1,40 @@
using NUnit.Framework;
using Unity.Entities;
using ProjectM.Simulation;
namespace ProjectM.Tests
{
/// <summary>
/// Setup smoke test: proves the DOTS toolchain compiles, source-generates, and ticks.
/// Boots a bare ECS world, registers <see cref="HeartbeatSystem"/> in the
/// SimulationSystemGroup, and asserts the component advances once per group update.
/// (Netcode client/server world boot is covered separately by the §3 Play Mode check.)
/// </summary>
public class HeartbeatSystemTests
{
[Test]
public void Heartbeat_Advances_Once_Per_SimulationGroup_Tick()
{
using var world = new World("HeartbeatTestWorld");
var simulationGroup = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
var heartbeatSystem = world.GetOrCreateSystem<HeartbeatSystem>();
simulationGroup.AddSystemToUpdateList(heartbeatSystem);
simulationGroup.SortSystems();
var entityManager = world.EntityManager;
var entity = entityManager.CreateEntity(typeof(Heartbeat));
Assert.AreEqual(0, entityManager.GetComponentData<Heartbeat>(entity).Tick,
"Heartbeat should start at 0.");
const int ticks = 8;
for (int i = 0; i < ticks; i++)
{
simulationGroup.Update();
}
Assert.AreEqual(ticks, entityManager.GetComponentData<Heartbeat>(entity).Tick,
"Heartbeat.Tick should advance exactly once per SimulationSystemGroup update.");
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 74e3326af426947cfaff903aa94ed9f0
@@ -0,0 +1,27 @@
{
"name": "ProjectM.Tests.EditMode",
"rootNamespace": "ProjectM.Tests",
"references": [
"ProjectM.Simulation",
"Unity.Entities",
"Unity.Collections",
"Unity.Mathematics",
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"nunit.framework.dll"
],
"autoReferenced": false,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1fc76dfd7bbd349d188d6561a2e30e0d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: