Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.2.0] - 2026-05-07¶
Large redesign pass covering package consolidation, accessor permissions, heap-backed collections, source-gen diagnostics, native pointer internals, and editor tooling. All breaking changes are mechanical text-level migrations unless otherwise noted.
Added¶
- Single-package layout.
com.trecs.serializationmerged intocom.trecs.core— the project is now a single UPM package. - Accessor roles. New
AccessorRoleenum (Fixed,Variable,Unrestricted) replaces the previousSystemPhase/IsEditorparameters. The role drives component read/write rules, structural-change rules, and heap-allocation rules in one place. - Heap-backed collection types.
TrecsList<T>,TrecsDictionary<TKey, TValue>, andTrecsArray<T>— deterministic, serializable, heap-allocated collections that can live inside ECS components. Each has separateRead/Writewrappers with version-checked safety guards that hold in shipping builds. BlobBuilder/BlobArray<T>/BlobRef<T>. Build relocatable blob allocations (root struct + trailing arrays) that can be handed toNativeSharedPtr.AllocTakingOwnership.- Input pointer types.
InputSharedPtr<T>,InputUniquePtr<T>,InputNativeSharedPtr<T>,InputNativeUniquePtr<T>for frame-scoped input data that participates in the input recording pipeline. [NonCopyable]/[Copyable]attributes. Prevent accidental by-value copies of structs (includingIEntityComponentby default). Source-gen diagnostics TRECS118–120.[Immutable]attribute. Enforces that types stored viaSharedPtr<T>are immutable (readonly fields, no public setters). Source-gen diagnostics TRECS125–127.- Determinism analyzers. TRECS128/129 flag
Dictionary/HashSetiteration in fixed-update systems; TRECS130 flags non-deterministic APIs (DateTime.Now,System.Random,UnityEngine.Random, etc.) in fixed-update systems. - System-control APIs.
WorldAccessor.SetSystemEnabled(int, EnableChannel, bool)with multi-channel AND semantics, plus deterministicWorldAccessor.SetSystemPausedfor replay-safe pauses.IsSystemEffectivelyEnabledquery for debug UIs. WorldAccessor.StepFixedFramefor single-frame stepping outside the system runner.- Trecs Player editor window. Record / playback / snapshot / scrub / fork / loop UI, with a Saves library for managing recordings and snapshots.
- Hierarchy editor window. Persisted expand/collapse, search, identity-based selection, per-entity component inspector with JSON edit.
WorldRegistry— static registry of activeWorldinstances.World.DebugName/WorldBuilder.SetDebugName(string)for editor dropdowns.World.Events.OnShutdown()— fires duringWorld.Dispose()afterRemoveAllEntitiesbut before infrastructure teardown.- Constructor-positional shorthand on tag attributes.
[ForEachEntity],[SingleEntity], and[FromWorld]accept tags asparams Type[]— e.g.[ForEachEntity(typeof(EcsTags.Enemy))]. [SingleEntity]is now per-parameter / per-field and works in plainExecute, mixed with[ForEachEntity],[WrapAsJob]auto-generated jobs, and hand-written job-struct fields.[GlobalIndex]parameter attribute on iterationExecutemethods — receives the packed 0..N-1 index across all groups. Job-side only.[Serializable]auto-emitted onIEntityComponentpartials., for use with Hierarchy editor window to allow changing entities dynamically at runtime via unity inspector- Recording system rewritten as
RecordingBundle. New surface:BundleRecorder,BundlePlayer,RecordingBundle,RecordingBundleSerializer. A bundle is a single self-contained replayable session: initial snapshot + input queue + sparse desync checksums + auto-anchor snapshots + user snapshots. EntityHandle.TryToEntity(WorldAccessor)overload.- Source-gen diagnostics. ~80 structured diagnostics (TRECS001–TRECS130) with dedicated tests.
- New samples.
10_DynamicCollections(renamed from10_Pointers),13_AspectInterfaces,14_BlobSeedPattern,15_ReactiveEvents,16_MultipleWorlds,17_HeightmapBlobs.11_Snakemoved fromcom.trecs.serializationinto the core tutorials.
Changed (breaking)¶
com.trecs.serializationmerged intocom.trecs.core. The project is now a single package. Dropcom.trecs.serializationfrom yourPackages/manifest.json.HeapAccessorremoved as separate class, folded intoWorldAccessor.world.Heap.AllocShared(...)becomesworld.AllocShared(...)directly.EntityAccessorref struct removed. Operations moved to extension methods onEntityHandle/EntityIndex— e.g.entity.Component<T>(world),entity.SetTag<T>(world).NativeSharedPtr<T>rearchitected. Struct shrinks from 12B to 4B (chunked directory replaces hash-map resolver, enabling concurrent Burst-visible allocation). API:DisposeHandle→DecrementRef,ptr.BlobId→ptr.GetBlobId(world).[ExecutesAfter]/[ExecutesBefore]renamed to[ExecuteAfter]/[ExecuteBefore].[Phase(...)]renamed to[ExecuteIn(...)].SetDefrenamed toEntitySet(internal storage toEntitySetStorage).- Accessor creation API.
World.CreateAccessor(string)removed. UseWorld.CreateAccessor(AccessorRole, string). [VariableUpdateOnly]enforced symmetrically. Writes blocked from non-Fixedphases;[Constant]writes blocked outside fixed-update. Support on entity sets removed (use templates).[FixedUpdateOnly]attribute removed. Fixed-update systems already have full write permission.- Aspect interfaces detected via
IAspectmarker instead of[AspectInterface]attribute. ITemplatefield declarations must omit access modifiers (TRECS034 reworked). Generator suppresses CS0169/CS0414/CS0649/IDE0051/IDE0052.IHasTags<...>renamed toITagged<...>.IHasPartition<...>replaced byIPartitionedBy<...>with dimension-based semantics. Each declaration is one dimension; multiple declarations cross-product automatically. New arity-1 formIPartitionedBy<T>for presence/absence.MoveToremoved;SetTag<T>/UnsetTag<T>are the only structural tag-change verbs. Multiple calls on the same entity in one submission coalesce; same-dim conflicts throw.[ForEachEntity(..., Without = typeof(T))]queries the absent partition of a presence/absence dimension.- Native collection cleanup. Sequence-shape collections standardize on signed-
intLength.IsEmpty()→IsEmptyproperty.NativeBuffercollapses read/write pointer accessors intoGetRawPointer. FixedArray2/16/128<T>indexer is read-only. Writes go througharr.Mut(i) = value.BlobPtr<T>/NativeBlobPtr<T>moved toTrecs.Internal. UseSharedPtr<T>/NativeSharedPtr<T>viaWorldAccessor.- Heap auto-ID allocation removed. Variable-update systems can no longer allocate persistent blobs.
SerializationFlagsis now bit-flags (longbitmask, values are powers of two).- Fast-forward API targets a frame, not a time.
SystemRunner.StepFramerenamedStepFixedFrame.ISystem.OnReadyruns in execute order (Input → Fixed → EarlyPresentation → Presentation → LatePresentation), not registration order.ISystem.OnReadyruns after the global entity is submitted.OnAddedsubscriptions fromOnReadywon't fire for global-entity creation.IComponentAccessRecorderrenamed toIAccessRecorder.EntityHandle.UniqueIdrenamed toId.MissingInputBehaviorvalues shortened:ResetToDefault→Reset,RetainCurrent→Retain.- "Bookmark" terminology replaced with "Snapshot" throughout recording system.
- Frame-event names made symmetric.
OnSubmission→OnSubmissionCompleted,OnPostApplyInputs→OnInputsApplied. NewOnVariableUpdateCompletedevent. QueryBuildermethod renames:Single→SingleHandle,EntityHandles→Handles,EntityIndices→Indices.RemoveAllEntitiesOnDisposesetting removed — entities are always removed on dispose.[SingleEntity]is per-parameter / per-field. The previous method-level form no longer compiles.PtrHandleis now areadonly struct.NativeArraySerializer<T>/NativeListSerializer<T>accept anAllocatorconstructor parameter (defaulting toPersistent).IEnumerableremoved from Trecs collection types to prevent accidental boxing allocations.10_Pointerssample renamed to10_DynamicCollections.13_SaveGamesample removed.
Changed¶
- Source-gen polish. Nested-class scope support, consolidated tag parsing, unified
[SingleEntity]emit path, value-equatable pipeline models for effective incremental cache,[GeneratedCode]attribute stamped on all generated types. - System-effectively-enabled display: hierarchy rows grayed when disabled.
- Submission pipeline optimized with Burst-jobified parallel fill, per-group staging bags, native component layout metadata.
- NativeHeap serialization optimized with struct blits and direct chunk walk.
BinarySerializationReaderrefactored to operate onReadOnlyMemory<byte>instead ofMemoryStream.
Removed¶
com.trecs.serializationpackage (merged intocom.trecs.core).DenseDictionary<TKey,TValue>,DenseHashSet<T>,NativeDenseDictionary<TKey,TValue>(replaced byIterableDictionary/IterableHashSet/NativeIterableDictionary).FastList<T>,ReadOnlyFastList<T>,LocalReadOnlyFastList<T>.HeapAccessorclass (folded intoWorldAccessor).EntityAccessorref struct.SimpleResizableBuffer<T>.[FixedUpdateOnly]attribute.[AspectInterface]attribute andAspectValidator.ValidateUsagePatterns.warnOnMissingparameter on[Input(...)].RecordingHandler/PlaybackHandler/AutoRecordingSnapshot/PlaybackStartParams/RecordingMetadata(replaced byBundleRecorder/BundlePlayer/RecordingBundle).World.AllocShared/World.AllocUnique(useWorldAccessorallocation methods).NativeAllocTracker(relies on Unity's built-in native-leak detection).- Legacy
Group.csruntime type (GroupIndexis the canonical handle). FixedTypeCommon.cs.SerializableByteArraySerializer(replaced byWriteBytes/ReadBytes).IStableHashProvider(collapsed intoGetHashCode).SharedNativeInt.- Per-component R/W access badges from the entity inspector.
- Stale diagnostic descriptors: TRECS006, 010, 011, 014, 017, 018, 019, 021, plus reserved-but-never-shipped gaps.
AccessorRole.Bypass/AccessorRole.Input(useUnrestricted; input permissions auto-derived from[ExecuteIn(Input)]).World.CreateAccessor(string)overload.RemoveAllEntitiesOnDisposesetting.
[0.1.0] - 2026-04-18¶
Added¶
- Initial release