diff --git a/docs/nuget-packaging.md b/docs/nuget-packaging.md index 841deedf..7894fe5e 100644 --- a/docs/nuget-packaging.md +++ b/docs/nuget-packaging.md @@ -25,7 +25,7 @@ closure through UPM rather than NuGet restore. Install the Unity package from the immutable release tag: ```text -https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v2.0.0 +https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v3.0.0 ``` ## Rolling back across the store format diff --git a/packages/cultmath/src/CultMath/CultMath.csproj b/packages/cultmath/src/CultMath/CultMath.csproj index ed99c004..d3846d4f 100644 --- a/packages/cultmath/src/CultMath/CultMath.csproj +++ b/packages/cultmath/src/CultMath/CultMath.csproj @@ -10,7 +10,7 @@ GameCult.Math MIT AND MPL-2.0 AND Apache-2.0 - 0.5.0 + 0.5.1 Clean-room C# math shaped for HLSL-style renderer code. GameCult README.md diff --git a/packages/cultmath/unity/org.gamecult.cultmath/CHANGELOG.md b/packages/cultmath/unity/org.gamecult.cultmath/CHANGELOG.md index 7edfa1b2..ebe21e7d 100644 --- a/packages/cultmath/unity/org.gamecult.cultmath/CHANGELOG.md +++ b/packages/cultmath/unity/org.gamecult.cultmath/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this package are documented in this file. Earlier releases (0.2.0-0.2.3) predate this package's changelog and are not backfilled here; see `docs/semver-policy.md` for why. -## [Unreleased] +## [0.5.1] - 2026-11-11 ### Added diff --git a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll index 205d3f9b..7757c254 100644 Binary files a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll and b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll differ diff --git a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb index 9f865c09..e0991c71 100644 Binary files a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb and b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb differ diff --git a/packages/cultmath/unity/org.gamecult.cultmath/package.json b/packages/cultmath/unity/org.gamecult.cultmath/package.json index 20ffe196..e06e6c89 100644 --- a/packages/cultmath/unity/org.gamecult.cultmath/package.json +++ b/packages/cultmath/unity/org.gamecult.cultmath/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.cultmath", "displayName": "CultMath", - "version": "0.5.0", + "version": "0.5.1", "unity": "2021.3", "description": "Precompiled CultMath numeric primitives and matching HLSL semantics for GameCult Unity runtimes.", "license": "MIT AND MPL-2.0 AND Apache-2.0", diff --git a/tests/GameCult.Caching.Tests/UniqueIndexVectorTests.cs b/tests/GameCult.Caching.Tests/UniqueIndexVectorTests.cs index e3be8c8f..23520310 100644 --- a/tests/GameCult.Caching.Tests/UniqueIndexVectorTests.cs +++ b/tests/GameCult.Caching.Tests/UniqueIndexVectorTests.cs @@ -352,6 +352,11 @@ namespace GameCult.Caching.Tests private static readonly Rec[] RepullAfter = Items_(("item:a1", "A"), ("item:b1", "B"), ("item:b2", "B"), ("item:c1", "A")); private static readonly Rec[] KeyCaseRecords = Items_(("a", "S"), ("z", "S"), ("B", "T"), ("C", "T")); private static readonly Rec[] HolderCaseRecords = Items_(("a", "S"), ("A", "S")); + private static readonly Rec[] CrossSchemaRecords = { new("x:1", Alpha, "P"), new("y:1", Beta, "P") }; + // Distinct under any trim, case-fold, NFC or NFKC of the value: 'S' and 's', 'S' and 'S ', NFC and NFD, fullwidth S. + private static readonly Rec[] DistinctValueRecords = Items_( + ("k:1", "S"), ("k:2", "s"), ("k:3", "S "), ("k:4", "\u00E9"), ("k:5", "e\u0301"), ("k:6", "\uFF33"), ("k:7", " S")); + private static readonly Rec[] NormalKeyRecords = Items_(("\u00E9", "S"), ("e\u0301", "S")); private static readonly Rec[] KeyPunctuationRecords = Items_(("_", "S"), ("a", "S"), ("Z", "T"), ("b", "T")); private static readonly Rec[] SurrogateGroupRecords = Items_(("\uE000", "S"), ("\uE000b", "S"), ("\U0001F600", "T"), ("\U0001F600b", "T")); @@ -362,6 +367,8 @@ namespace GameCult.Caching.Tests ("key-case-store.cc", KeyCaseRecords), ("key-punctuation-store.cc", KeyPunctuationRecords), ("surrogate-groups-store.cc", SurrogateGroupRecords), ("holder-case-store.cc", HolderCaseRecords), + ("cross-schema-store.cc", CrossSchemaRecords), ("distinct-values-store.cc", DistinctValueRecords), + ("normal-keys-store.cc", NormalKeyRecords), }; private static readonly Refusal SurrogateRefusal = new("k\U0001F600", "k\uE000", Item, "Sku"); @@ -371,6 +378,7 @@ namespace GameCult.Caching.Tests private static readonly Refusal RepullRefusal = new("item:a1", "item:c1", Item, "Sku"); private static readonly Refusal KeyCaseRefusal = new("B", "C", Item, "Sku"); private static readonly Refusal HolderCaseRefusal = new("A", "a", Item, "Sku"); + private static readonly Refusal NormalKeyRefusal = new("e\u0301", "\u00E9", Item, "Sku"); private static readonly Refusal KeyPunctuationRefusal = new("Z", "b", Item, "Sku"); private static readonly Refusal SurrogateGroupRefusal = new("\U0001F600", "\U0001F600b", Item, "Sku"); @@ -408,6 +416,20 @@ namespace GameCult.Caching.Tests // Rows 23-24: two holders of one value that differ only by case are two holders; a case-folding dedupe would see one. new("batch-holders-by-case", new[] { Open(), Commit(HolderCaseRecords) }, HolderCaseRefusal), new("load-holders-by-case", new[] { Open("holder-case-store.cc") }, HolderCaseRefusal), + // Row 25: the held `a` is replaced only by the exact key `a`, never by `A`. + new("batch-replaced-by-case", new[] { Open(), Commit(Items_(("a", "S"))), Commit(Items_(("A", "S"))) }, HolderCaseRefusal), + // Rows 26-31: identity is exact. One value in two schemas is two groups; values differing in case, trailing or leading space, normalisation form or width are two values; keys differing only by normalisation form are two holders. + new("batch-value-in-two-schemas", new[] { Open(), Commit(CrossSchemaRecords) }, null), + new("load-value-in-two-schemas", new[] { Open("cross-schema-store.cc") }, null), + new("batch-distinct-values", new[] { Open(), Commit(DistinctValueRecords) }, null), + new("load-distinct-values", new[] { Open("distinct-values-store.cc") }, null), + new("batch-keys-by-normal-form", new[] { Open(), Commit(NormalKeyRecords) }, NormalKeyRefusal), + new("load-keys-by-normal-form", new[] { Open("normal-keys-store.cc") }, NormalKeyRefusal), + // Rows 32-33: one landing record sharing two unique aliases with a held one; the least alias by code unit is named ('Alt' before 'Sku'; 'Sku' before 'alt'). + new("put-onto-a-held-pair", new[] { Open(), Commit(new Rec("m", Pair, "S", "X")), Commit(new Rec("a", Pair, "S", "X")) }, + new Refusal("a", "m", Pair, "Alt")), + new("put-onto-a-held-alias-pair", new[] { Open(), Commit(new Rec("m", Alias, "S", "X")), Commit(new Rec("a", Alias, "S", "X")) }, + new Refusal("a", "m", Alias, "Sku")), }; private static byte[] RefusalStoreBytes(Rec[] records) @@ -528,6 +550,7 @@ namespace GameCult.Caching.Tests var count = reader.ReadArrayHeader(); Assert.That(count, Is.EqualTo(Cases.Length)); var walked = 0; + var failed = new List(); for (var i = 0; i < count; i++) { Assert.That(reader.ReadArrayHeader(), Is.EqualTo(3)); @@ -588,6 +611,10 @@ namespace GameCult.Caching.Tests walked++; } + catch (AssertionException failure) + { + failed.Add($"{label}: {failure.Message}"); + } finally { cache?.Dispose(); @@ -595,7 +622,8 @@ namespace GameCult.Caching.Tests } } - Assert.That(walked, Is.EqualTo(24)); + Assert.That(failed, Is.Empty, "rows that failed"); + Assert.That(walked, Is.EqualTo(33)); } } } diff --git a/tests/vectors/unique-index/README.md b/tests/vectors/unique-index/README.md index 621ebe36..45e6ef71 100644 --- a/tests/vectors/unique-index/README.md +++ b/tests/vectors/unique-index/README.md @@ -19,7 +19,7 @@ reviewed commit. Other runtimes are held to the same canonical text and the same `" "` and `item:d` holds Sku `U+0085`. Written through a role Sku. - `blank-store.cc`: the same, only `item:c` and `item:d`. - `pair-store.cc`, `surrogate-store.cc`, `types-store.cc`, `repull-before.cc`, `repull-after.cc`, `alias-store.cc`, - `key-case-store.cc`, `key-punctuation-store.cc`, `surrogate-groups-store.cc`, `holder-case-store.cc`: single-file stores written like + `key-case-store.cc`, `key-punctuation-store.cc`, `surrogate-groups-store.cc`, `holder-case-store.cc`, `cross-schema-store.cc`, `distinct-values-store.cc`, `normal-keys-store.cc`: single-file stores written like `duplicate-store.cc`, through roles, for the rows of `refusals.msgpack` that open or pull them. Schemas `tests.unique_item`, `tests.uq_pair` (Sku and Alt both unique), `tests.uq_alias` (Sku and `alt` both unique), `tests.uq_alpha` and `tests.uq_beta`, each slots `[0: Sku string, 1: second string]`, schema version the name plus @@ -51,20 +51,29 @@ last succeeds and the last refuses with exactly the RULE text built from those f byte-identical. Schemas are those of the store files above; `second` is `Category` (plain) except in `tests.uq_pair` and `tests.uq_alias`, where it is `Alt` (unique, alias `Alt` and `alt` respectively). -The 13 rows of the spec are a floor; rows 14-24 extend it with orderings that a code-point, case-insensitive or +The 13 rows of the spec are a floor; rows 14-33 extend it with orderings that a code-point, case-insensitive or culture compare would flip. Rows, in file order: 1 batch-later-value-staged-first, 2 batch-surrogate-keys, 3 batch-interleaved-types, 4 batch-two-aliases, 5 held-then-landing, 6 held-in-the-least-group, 7 swap-off-a-held-value, 8 load-two-aliases, 9 load-surrogate-keys, 10 load-interleaved-types, 11 repull-held-pair, 12 load-repull-after, 13 commit-onto-a-loaded-holder, 14 batch-key-case (`B` before `a`), 15 batch-key-punctuation (`Z` before `_` before `a`), 16 batch-key-case-in-a-group, 17 batch-surrogate-groups (U+1F600 before U+E000, the reverse of code-point order), 18 batch-alias-case (alias `Sku` before `alt`), 19 load-alias-case, 20 load-key-case, 21 load-key-punctuation, 22 -load-surrogate-groups, 23 batch-holders-by-case (`a` and `A` holding one value: `A` before `a`), 24 load-holders-by-case. -Rows 19-22 and 24 open a store holding the records of rows 18, 14, 15, 17 and 23, so a runtime with no batch +load-surrogate-groups, 23 batch-holders-by-case (`a` and `A` holding one value: `A` before `a`), 24 load-holders-by-case, 25 batch-replaced-by-case (held `a`, then a commit of `A` on its value: `A` does not replace `a`), +26 batch-value-in-two-schemas (one value in `tests.uq_alpha` and `tests.uq_beta` at two keys: two groups, success), 27 +load-value-in-two-schemas, 28 batch-distinct-values (`S`, `s`, `S `, ` S`, U+00E9, `e`+U+0301, U+FF33 are seven values: success), 29 +load-distinct-values, 30 batch-keys-by-normal-form (keys U+00E9 and `e`+U+0301 holding one value are two holders, `e`+U+0301 first), +31 load-keys-by-normal-form, 32 put-onto-a-held-pair (held `m` and landing `a` share Sku and Alt in `tests.uq_pair`, one record per +commit: `Alt` is named before `Sku`), 33 put-onto-a-held-alias-pair (the same in `tests.uq_alias`: `Sku` before `alt`). +Rows 19-22, 24, 27, 29 and 31 open a store holding the records of rows 18, 14, 15, 17, 23, 26, 28 and 30, so a runtime with no batch commit still walks alias and cross-group key order. -A runtime performs every row its API can perform and asserts the count it walked: +A runtime performs every row its API can perform and asserts the count it walks. These are the counts a runtime must +assert, not a statement of which runtimes walk them today: -- C# and Rust: all 24. -- Python: 23, every row but 3 (`put_envelopes` takes one type). -- TypeScript: 12, rows 5, 8, 9, 10, 11, 12, 13, 19, 20, 21, 22 and 24 (no batch commit, so no row 1-4, 6, 7, 14-18 or 23; - `variants:idea:unique-index-runtimes.ts-batch-commit`). +- C# and Rust: all 33. +- Python: 31, every row but 3 and 26 (`put_envelopes` takes one type, so no batch of two types). +- TypeScript: 18, the rows with no multi-record commit: 5, 8, 9, 10, 11, 12, 13, 19, 20, 21, 22, 24, 25, 27, 29, 31, 32 and 33 + (no batch commit, so no row 1-4, 6, 7, 14-18, 23, 26, 28 or 30; `variants:idea:unique-index-runtimes.ts-batch-commit`). + +Not pinned: the schema-name tiebreak. Record keys are unique across a whole cache, so two types never hold the same key and +two groups can never tie on alias and key pair; the final `schema` comparison cannot decide a refusal. diff --git a/tests/vectors/unique-index/cross-schema-store.cc b/tests/vectors/unique-index/cross-schema-store.cc new file mode 100644 index 00000000..1dd2fb66 Binary files /dev/null and b/tests/vectors/unique-index/cross-schema-store.cc differ diff --git a/tests/vectors/unique-index/distinct-values-store.cc b/tests/vectors/unique-index/distinct-values-store.cc new file mode 100644 index 00000000..6eabdd96 Binary files /dev/null and b/tests/vectors/unique-index/distinct-values-store.cc differ diff --git a/tests/vectors/unique-index/normal-keys-store.cc b/tests/vectors/unique-index/normal-keys-store.cc new file mode 100644 index 00000000..27f36b96 Binary files /dev/null and b/tests/vectors/unique-index/normal-keys-store.cc differ diff --git a/tests/vectors/unique-index/refusals.msgpack b/tests/vectors/unique-index/refusals.msgpack index bf2bd7ca..34fc402d 100644 Binary files a/tests/vectors/unique-index/refusals.msgpack and b/tests/vectors/unique-index/refusals.msgpack differ diff --git a/unity/org.gamecult.cultlib/CHANGELOG.md b/unity/org.gamecult.cultlib/CHANGELOG.md index 3d03439a..b5ff6419 100644 --- a/unity/org.gamecult.cultlib/CHANGELOG.md +++ b/unity/org.gamecult.cultlib/CHANGELOG.md @@ -2,11 +2,9 @@ All notable changes to this package are documented in this file. -## [Unreleased] +## [3.0.0] - 2026-11-11 -Releases as 3.0.0 (major). - -### Breaking (major) +### Breaking - A single-file store flush refuses a file it cannot read (empty, truncated, an unreadable stamp or body) with `CultStoreUnreadableException` and leaves the file as it is. A flush used to replace such a file. A write set cannot merge with a disk it cannot read, so the file is repaired or removed by its owner before the store writes again. - A single-file store reads v1, v2 and v3 stamps and refuses v4 and later by name; a directory store reads v4 and v5 and refuses v6 and later by name. Each judges the stamp before the body, so an unreadable body never makes a newer store look like damage. diff --git a/unity/org.gamecult.cultlib/README.md b/unity/org.gamecult.cultlib/README.md index e118ac65..30db7fba 100644 --- a/unity/org.gamecult.cultlib/README.md +++ b/unity/org.gamecult.cultlib/README.md @@ -11,19 +11,19 @@ and OpenSSL license notices are included under `Third Party Notices`. Build it with `scripts/build-unity-package.ps1`. Do not edit generated plugin assemblies in the package output. -Install version `2.0.0` through Unity Package Manager with: +Install version `3.0.0` through Unity Package Manager with: ```text -https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v2.0.0 +https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v3.0.0 ``` -The package depends on `org.gamecult.cultmath` (exactly 0.5.0) and does not +The package depends on `org.gamecult.cultmath` (exactly 0.5.1) and does not carry its own `CultMath.dll`. Unity Package Manager resolves git packages only from the project manifest, so add CultMath beside CultLib in `Packages/manifest.json`: ```text -"org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.5.0" +"org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.5.1" ``` CultMesh chooses mapped memory for reachable same-machine bodies and advertised diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll index bf05fec2..5b040bec 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.pdb index bfe11807..d2629dfd 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.MessagePack.pdb differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.dll index 8e7b88f1..cff0d028 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.pdb index 3fb019e1..d952c867 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Caching.pdb differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll index 2dd55355..f9674828 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.pdb index 1635f093..f881acde 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Logging.pdb differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll index 6e138fd5..9bff9912 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.pdb index 021de32d..62bdb6b3 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.Quic.Native.pdb differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll index ceb2fbf4..f7a86dde 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.pdb index 3074fbd6..d27197b5 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Mesh.pdb differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll index 21e64ce1..da269490 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.WebSockets.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll index dd6482f9..065ac7c5 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.dll differ diff --git a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb index 4fcf53c6..8cb5dad7 100644 Binary files a/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb and b/unity/org.gamecult.cultlib/Runtime/Plugins/GameCult.Networking.pdb differ diff --git a/unity/org.gamecult.cultlib/package.json b/unity/org.gamecult.cultlib/package.json index 19e42b58..1111d3fb 100644 --- a/unity/org.gamecult.cultlib/package.json +++ b/unity/org.gamecult.cultlib/package.json @@ -1,10 +1,10 @@ { "name": "org.gamecult.cultlib", "displayName": "CultLib", - "version": "2.0.1", + "version": "3.0.0", "unity": "2021.3", "dependencies": { - "org.gamecult.cultmath": "0.5.0" + "org.gamecult.cultmath": "0.5.1" }, "description": "CultCache, CultNet, and CultMesh managed runtime assemblies for Unity.", "license": "MIT",