From 66f77a2e35941b81d14182c8152f5bda8ba7b11b Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 10 Jul 2026 15:29:44 +0100 Subject: [PATCH] Publish portable C# fields contracts --- plugins/eve-plugin-fields/plugin.json | 7 ++ .../eve-plugin-fields/test/plugin.test.mjs | 11 ++ .../org.gamecult.eve.plugin-fields/README.md | 5 + .../Runtime/EveFieldsContracts.cs | 113 ++++++++++++++++++ .../Runtime/GameCult.Eve.PluginFields.asmdef | 7 ++ .../package.json | 8 ++ 6 files changed, 151 insertions(+) create mode 100644 plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/README.md create mode 100644 plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/EveFieldsContracts.cs create mode 100644 plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/GameCult.Eve.PluginFields.asmdef create mode 100644 plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/package.json diff --git a/plugins/eve-plugin-fields/plugin.json b/plugins/eve-plugin-fields/plugin.json index 386299c..6dfa5f8 100644 --- a/plugins/eve-plugin-fields/plugin.json +++ b/plugins/eve-plugin-fields/plugin.json @@ -29,6 +29,13 @@ } }, "stateSchemas": ["gamecult.fields.surface2d.v1", "gamecult.fields.scalar.v1", "gamecult.fields.vector.v1", "gamecult.fields.gravity.v1", "gamecult.fields.splats.v1", "gamecult.fields.objects.v1"], + "contractPackages": [ + { + "runtime": "unity-csharp", + "package": "org.gamecult.eve.plugin-fields", + "path": "plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields" + } + ], "fixtures": [ { "fixtureId": "fields-surface-basic", "schema": "gamecult.fields.surface2d.v1", "path": "plugins/eve-plugin-fields/fixtures/basic-field.json" } ], diff --git a/plugins/eve-plugin-fields/test/plugin.test.mjs b/plugins/eve-plugin-fields/test/plugin.test.mjs index 864c270..9d75db4 100644 --- a/plugins/eve-plugin-fields/test/plugin.test.mjs +++ b/plugins/eve-plugin-fields/test/plugin.test.mjs @@ -1,5 +1,6 @@ import assert from "node:assert/strict"; import test from "node:test"; +import { readFileSync } from "node:fs"; import { dispatch } from "../src/plugin.mjs"; function request(operation, input = {}) { @@ -39,3 +40,13 @@ test("measures field domains without mutating provider state", () => { assert.equal(result.channelCount, 1); assert.equal(result.preservesProviderAuthority, true); }); + +test("publishes a runtime-neutral Unity contract package", () => { + const packageRoot = new URL("../unity/org.gamecult.eve.plugin-fields/", import.meta.url); + const manifest = JSON.parse(readFileSync(new URL("package.json", packageRoot), "utf8")); + const contracts = readFileSync(new URL("Runtime/EveFieldsContracts.cs", packageRoot), "utf8"); + assert.equal(manifest.name, "org.gamecult.eve.plugin-fields"); + assert.match(contracts, /interface IEveFieldsSplatsDocument/); + assert.match(contracts, /gamecult\.fields\.splats\.v1/); + assert.doesNotMatch(contracts, /UnityEngine|Aetheria|MessagePack|GameCult\.Caching/); +}); diff --git a/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/README.md b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/README.md new file mode 100644 index 0000000..8584a0c --- /dev/null +++ b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/README.md @@ -0,0 +1,5 @@ +# Eve Fields Plugin Contracts + +This package owns the portable C# view of `gamecult.fields.*` documents. It has +no Unity rendering, provider state, transport, or command authority. Providers +implement these read-only interfaces; Unity runtime adapters consume them. diff --git a/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/EveFieldsContracts.cs b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/EveFieldsContracts.cs new file mode 100644 index 0000000..075a8e4 --- /dev/null +++ b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/EveFieldsContracts.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; + +namespace GameCult.Eve.PluginFields +{ + public static class EveFieldsSchemas + { + public const string Surface2D = "gamecult.fields.surface2d.v1"; + public const string Objects = "gamecult.fields.objects.v1"; + public const string Gravity = "gamecult.fields.gravity.v1"; + public const string Splats = "gamecult.fields.splats.v1"; + } + + public static class EveFieldsSplatChannels + { + public const int Visibility = 0; + public const int Gravity = 1; + public const int GravityWave = 2; + public const int Influence = 3; + public const int Tint = 4; + } + + public static class EveFieldsSplatLayerKeys + { + public const string GravityHeight = "gravity.height"; + public const string GravityWave = "gravity.wave"; + public const string Visibility = "visibility.mask"; + public const string FogSurfaceHeight = "fog.surface_height"; + public const string FogPatchHeight = "fog.patch_height"; + public const string FogPatch = "fog.patch"; + public const string FogTint = "fog.tint"; + public const string Influence = "influence.mask"; + } + + public static class EveFieldsSplatBlendModes + { + public const string Add = "add"; + public const string Max = "max"; + public const string Alpha = "alpha"; + } + + public static class EveFieldsSplatSourceKinds + { + public const int Constant = 0; + public const int SimplexNoise = 1; + public const int AnimatedSimplexNoise = 2; + } + + public static class EveFieldsSplatFalloffs + { + public const int Solid = 0; + public const int Linear = 1; + public const int Smooth = 2; + public const int InverseSmooth = 3; + } + + public interface IEveFieldsViewport + { + double MinX { get; } + double MinY { get; } + double MaxX { get; } + double MaxY { get; } + } + + public interface IEveFieldsSplatLayer + { + string LayerKey { get; } + string DisplayName { get; } + int Channel { get; } + string BlendMode { get; } + string GraphicsFormat { get; } + bool ClearBeforeDraw { get; } + double ClearR { get; } + double ClearG { get; } + double ClearB { get; } + double ClearA { get; } + } + + public interface IEveFieldsSplatSoa + { + int Count { get; } + IReadOnlyList CenterX { get; } + IReadOnlyList CenterY { get; } + IReadOnlyList HalfExtentX { get; } + IReadOnlyList HalfExtentY { get; } + IReadOnlyList RotationCos { get; } + IReadOnlyList RotationSin { get; } + IReadOnlyList Channel { get; } + IReadOnlyList Falloff { get; } + IReadOnlyList ValueR { get; } + IReadOnlyList ValueG { get; } + IReadOnlyList ValueB { get; } + IReadOnlyList ValueA { get; } + IReadOnlyList SourceKey { get; } + IReadOnlyList LayerIndex { get; } + IReadOnlyList SourceKind { get; } + IReadOnlyList FrequencyX { get; } + IReadOnlyList FrequencyY { get; } + IReadOnlyList PhaseX { get; } + IReadOnlyList PhaseY { get; } + IReadOnlyList AnimationSpeed { get; } + IReadOnlyList SourceFlags { get; } + } + + public interface IEveFieldsSplatsDocument + { + string Schema { get; } + long FrameId { get; } + double SimulationTimeSeconds { get; } + IEveFieldsViewport Viewport { get; } + IReadOnlyList Layers { get; } + IEveFieldsSplatSoa Splats { get; } + } +} diff --git a/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/GameCult.Eve.PluginFields.asmdef b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/GameCult.Eve.PluginFields.asmdef new file mode 100644 index 0000000..b1ae4e7 --- /dev/null +++ b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/Runtime/GameCult.Eve.PluginFields.asmdef @@ -0,0 +1,7 @@ +{ + "name": "GameCult.Eve.PluginFields", + "rootNamespace": "GameCult.Eve.PluginFields", + "references": [], + "autoReferenced": true, + "noEngineReferences": true +} diff --git a/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/package.json b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/package.json new file mode 100644 index 0000000..a925186 --- /dev/null +++ b/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields/package.json @@ -0,0 +1,8 @@ +{ + "name": "org.gamecult.eve.plugin-fields", + "version": "0.1.0", + "displayName": "Eve Fields Plugin Contracts", + "description": "Runtime-neutral C# contracts for gamecult.fields documents.", + "unity": "2022.3", + "license": "MPL-2.0" +}