Server-side scenario execution: new Rudder.Core.dll, realtime/planstore glue removed

- Rudder.Core.dll rebuilt from csharp-sdk effects rewrite (96,768 bytes)
- Realtime/ adapters, UnityRealtimeTransportFactory, UnityPlanStateStore,
  UnityPlanScheduler, WebGL jslib and RealtimeUrl config deleted (with .meta)
- Scenarios sample rewired to client.Effects; samples login path updated
- AGENTS.md/README/CHANGELOG/package docs + agent skill updated; realtime.md skill doc removed
This commit is contained in:
edmand46
2026-09-04 14:23:38 +03:00
parent 22805173eb
commit 6d115f158e
71 changed files with 3338 additions and 1034 deletions
@@ -0,0 +1,305 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 0000000000000000d000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 10
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 2
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 1
m_PVRFilteringGaussRadiusAO: 1
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &100001
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 100003}
- component: {fileID: 100002}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!20 &100002
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100001}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0.12, g: 0.13, b: 0.15, a: 1}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &100003
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100001}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &200001
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 200003}
- component: {fileID: 200002}
m_Layer: 0
m_Name: Sample
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &200002
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 200001}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 72ab1e68bc9f48588c945a033026622e, type: 3}
m_Name:
m_EditorClassIdentifier: Rudder.Unity.Samples::RudderSdk.Unity.Samples.ScenariosSample
nickname: Player
region: global
language: en
loginEvent: player_login
roundEvent: demo_round_finished
--- !u!4 &200003
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 200001}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &300001
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 300003}
- component: {fileID: 300002}
m_Layer: 0
m_Name: Rudder
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &300002
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 300001}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: efb778515f4ca44289f365faa2acecd7, type: 3}
m_Name:
m_EditorClassIdentifier: Rudder.Unity::RudderSdk.Unity.Rudder
_configuration: {fileID: 11400000, guid: 98d531126f0d748ceacfb85bdd959e81, type: 2}
--- !u!4 &300003
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 300001}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 100003}
- {fileID: 300003}
- {fileID: 200003}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d57ceb109f374f93862dd52f93d5961f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,201 @@
using System;
using System.Threading.Tasks;
using RudderSdk.Core;
using UnityEngine;
using RudderSdk.Unity;
namespace RudderSdk.Unity.Samples
{
public class ScenariosSample : MonoBehaviour
{
[SerializeField] string nickname = "Player";
[SerializeField] string region = "global";
[SerializeField] string language = "en";
[SerializeField] string loginEvent = "player_login";
[SerializeField] string roundEvent = "demo_round_finished";
readonly SamplePage _page = new SamplePage(
"Scenarios",
"Subscribe to scenario effects, trigger an event, then resolve nodes from UI.");
StoreOfferEffect _offer;
bool _subscribed;
void Start()
{
_page.Run(this, async () =>
{
await Rudder.Initialize().Auth.LoginWithDeviceAsync(region, language, nickname);
Subscribe();
_page.SetStatus("Signed in, listening for scenario effects");
_page.Log("Subscribed to Effects.On*");
});
}
void OnDestroy()
{
Unsubscribe();
}
void OnGUI()
{
_page.Draw(() =>
{
GUILayout.BeginHorizontal();
if (_page.Button("Trigger " + loginEvent))
_page.Run(this, () => Trigger(loginEvent));
if (_page.Button("Trigger " + roundEvent))
_page.Run(this, () => Trigger(roundEvent));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (_page.Button("Buy offer"))
_page.Run(this, BuyOffer);
if (_page.Button("Decline offer"))
DeclineOffer();
GUILayout.EndHorizontal();
});
}
async Task Trigger(string eventName)
{
var client = Rudder.Initialize();
Subscribe();
_page.Log("Scenario.TriggerAsync(\"" + eventName + "\")");
await client.Scenario.TriggerAsync(eventName);
_page.SetStatus("Triggered " + eventName);
}
async Task BuyOffer()
{
if (_offer == null)
{
_page.SetStatus("No store-offer effect.", true);
return;
}
var client = Rudder.Initialize();
var storeSlug = _offer.Get("storeSlug", "cozy-camp-shop");
var store = await client.Stores.GetAsync(storeSlug);
var offer = store?.Offers != null && store.Offers.Count > 0 ? store.Offers[0] : null;
if (offer == null)
throw new InvalidOperationException("Store " + storeSlug + " has no offers.");
_page.Log("Stores.PurchaseAsync(" + storeSlug + ", " + offer.Id + ")");
var response = await client.Stores.PurchaseAsync(storeSlug, offer.Id);
if (response != null && response.Success != true)
throw new InvalidOperationException(response.Error ?? "Purchase rejected");
_offer.Purchase();
_offer = null;
_page.SetStatus("Offer purchased");
_page.Log("StoreOfferEffect.Purchase()");
}
void DeclineOffer()
{
if (_offer == null)
{
_page.SetStatus("No store-offer effect.", true);
return;
}
_offer.Decline();
_offer = null;
_page.SetStatus("Offer declined");
_page.Log("StoreOfferEffect.Decline()");
}
void Subscribe()
{
if (_subscribed || Rudder.State != RudderState.Ready)
return;
var effects = Rudder.Client.Effects;
effects.OnNotification += OnNotification;
effects.OnStoreOffer += OnStoreOffer;
effects.OnWait += OnWait;
effects.OnQuest += OnQuest;
effects.OnLeaderboard += OnLeaderboard;
effects.OnBattlePass += OnBattlePass;
effects.OnBattlePassLevel += OnBattlePassLevel;
effects.OnScenarioCompleted += OnCompleted;
effects.OnScenarioFailed += OnFailed;
_subscribed = true;
}
void Unsubscribe()
{
if (!_subscribed || Rudder.State != RudderState.Ready)
return;
var effects = Rudder.Client.Effects;
effects.OnNotification -= OnNotification;
effects.OnStoreOffer -= OnStoreOffer;
effects.OnWait -= OnWait;
effects.OnQuest -= OnQuest;
effects.OnLeaderboard -= OnLeaderboard;
effects.OnBattlePass -= OnBattlePass;
effects.OnBattlePassLevel -= OnBattlePassLevel;
effects.OnScenarioCompleted -= OnCompleted;
effects.OnScenarioFailed -= OnFailed;
_subscribed = false;
}
void OnNotification(NotificationEffect effect)
{
var title = effect.Title;
var message = effect.Message;
_page.Log("OnNotification: " + title + " " + message);
_page.SetOutput(title + "\n" + message);
effect.Done();
}
void OnStoreOffer(StoreOfferEffect effect)
{
_offer = effect;
var storeSlug = effect.Get("storeSlug", "cozy-camp-shop");
_page.Log("OnStoreOffer: " + storeSlug);
_page.SetOutput("Store offer from " + storeSlug + "\nUse Buy offer or Decline offer.");
_page.SetStatus("Store offer waiting");
}
void OnWait(WaitEffect effect)
{
_page.Log("OnWait until " + effect.DeadlineUtc.ToString("O"));
}
void OnQuest(QuestEffect effect)
{
_page.Log("OnQuest: " + effect.NodeId);
}
void OnLeaderboard(LeaderboardEffect effect)
{
_page.Log("OnLeaderboard: " + effect.NodeId);
effect.End();
}
void OnBattlePass(BattlePassEffect effect)
{
_page.Log("OnBattlePass: " + effect.NodeId);
}
void OnBattlePassLevel(BattlePassLevelEffect effect)
{
_page.Log("OnBattlePassLevel: " + effect.NodeId);
}
void OnCompleted(ScenarioCompletedEffect effect)
{
_page.Log("OnScenarioCompleted: " + effect.RunId);
_page.SetStatus("Scenario completed");
}
void OnFailed(ScenarioFailedEffect failed)
{
_page.Log("OnScenarioFailed: " + failed.NodeId + " " + failed.Exception.Message);
_page.SetStatus(failed.Exception.Message, true);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72ab1e68bc9f48588c945a033026622e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: