Publish portable C# fields contracts

This commit is contained in:
Meta Vens 2026-07-10 15:29:44 +01:00
commit 66f77a2e35
6 changed files with 151 additions and 0 deletions

View file

@ -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" }
],

View file

@ -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/);
});

View file

@ -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.

View file

@ -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<double> CenterX { get; }
IReadOnlyList<double> CenterY { get; }
IReadOnlyList<double> HalfExtentX { get; }
IReadOnlyList<double> HalfExtentY { get; }
IReadOnlyList<double> RotationCos { get; }
IReadOnlyList<double> RotationSin { get; }
IReadOnlyList<int> Channel { get; }
IReadOnlyList<int> Falloff { get; }
IReadOnlyList<double> ValueR { get; }
IReadOnlyList<double> ValueG { get; }
IReadOnlyList<double> ValueB { get; }
IReadOnlyList<double> ValueA { get; }
IReadOnlyList<string> SourceKey { get; }
IReadOnlyList<int> LayerIndex { get; }
IReadOnlyList<int> SourceKind { get; }
IReadOnlyList<double> FrequencyX { get; }
IReadOnlyList<double> FrequencyY { get; }
IReadOnlyList<double> PhaseX { get; }
IReadOnlyList<double> PhaseY { get; }
IReadOnlyList<double> AnimationSpeed { get; }
IReadOnlyList<double> SourceFlags { get; }
}
public interface IEveFieldsSplatsDocument
{
string Schema { get; }
long FrameId { get; }
double SimulationTimeSeconds { get; }
IEveFieldsViewport Viewport { get; }
IReadOnlyList<IEveFieldsSplatLayer> Layers { get; }
IEveFieldsSplatSoa Splats { get; }
}
}

View file

@ -0,0 +1,7 @@
{
"name": "GameCult.Eve.PluginFields",
"rootNamespace": "GameCult.Eve.PluginFields",
"references": [],
"autoReferenced": true,
"noEngineReferences": true
}

View file

@ -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"
}