Files
rudder-csharp-sdk/CHANGELOG.md
T
edmand46 ef5624ee4e
CI / publish (push) Failing after 19s
CI / check (push) Successful in 28s
Release 1.0.0
2026-09-04 15:37:00 +03:00

170 lines
8.3 KiB
Markdown

# Changelog
## 1.0.0
Breaking change — major bump. The local scenario engine is replaced by a
server-driven effects client; the realtime websocket client is removed.
### Removed
- Local scenario runtime: `PlanRun`, `ExecutionPlan` walking, node sessions
(`NotificationSession`, `StoreOfferSession`, `LeaderboardSession`,
`WaitSession`, `QuestSession`, `BattlePassSession`,
`BattlePassLevelSession`, `ConfigChangedSession`), `RespondAsync` /
`Respond`, `RestoreAsync`, `Clear`, `ActiveRuns`, `IsRunning`,
`CurrentNodeId`, `OnConfigChanged`.
- `RudderClientOptions.PlanStateStore` / `IPlanStateStore` and
`IPlanScheduler` — no local plan persistence or delayed plan work.
- `RealtimeService` (`client.Realtime`), `RudderClientOptions.RealtimeUrl` /
`RealtimeTransportFactory`, `IRealtimeTransport` /
`IRealtimeTransportFactory`.
### Changed (breaking)
- `client.Scenario` is a trigger only: `TriggerAsync(eventName)` returns
`Task` (not started plans). Returned pending effects are ingested into
`client.Effects`.
- Subscribe to `client.Effects.On*` instead of `client.Scenario.On*`.
Sessions are now effect objects (`NotificationEffect`, `StoreOfferEffect`,
…). Complete them with the methods on the effect (`DoneAsync`,
`PurchaseAsync`/`DeclineAsync`, `EndAsync`/`ClaimAsync`, …).
- `client.Update(deltaTime)` is still required every frame — it now pumps
the effects client (30s `GET /sdk/v1/scenarios/pending` heartbeat +
wait-deadline checks), not a local DAG or a websocket.
- After login (or when constructed with a stored access token), the next
`Update` fetches pending effects. There is no `loginEvent` option; trigger
login-gated scenarios yourself.
### Migration
| Before | After |
|---|---|
| `client.Scenario.OnNotification` (and other `On*`) | `client.Effects.OnNotification` (same event names) |
| `NotificationSession` / `StoreOfferSession` / … | `NotificationEffect` / `StoreOfferEffect` / … |
| `session.CompleteAsync()` / `RespondAsync("output")` | `effect.DoneAsync()` (and the matching method on each effect) |
| `RudderClientOptions.PlanStateStore` + `RestoreAsync` | gone — server owns run state; pending fetch after login + heartbeat |
| `client.Realtime` | gone |
| `client.Update(deltaTime)` | still required (effects pump) |
## 0.4.0
- Generated DTOs live under `Models/` (`RudderSdk.Core.Models`). Wire fields
are nullable. `ListQuestsRequest` is gone; `Quests.ListAsync` POSTs with
no body. `BoundaryNode.WaitDeadline` is `DateTimeOffset?`.
- `LeaderboardSession.ClaimAsync` / `Claim` complete the leaderboard node
with handle `onClaim`. The server matches live rank to an authored place.
- `RewardClaimedAsync` / `RewardClaimed` are obsolete aliases and will be
removed in the next SDK version.
- `rank_not_eligible` on Claim leaves the session open (retry Claim or End);
it no longer fails the run.
## 0.3.0
### Removed
- UGC surface: `UgcService` (`client.Ugc`), the generated
`RudderSdk.Core.Models.Ugc` DTOs, `IUploadTransport` and
`RudderClientOptions.UploadTransport`. The server no longer exposes the UGC
endpoints.
### Changed (breaking)
- `BattlePassService` simple overloads sent empty scenario/node ids and always
failed server-side. Battle pass state is tied to a scenario battle pass
node, so the public API now mirrors the web SDK: `GetProgressAsync(scenarioId,
nodeId)` and the request-DTO overloads `AddXpAsync`, `ClaimRewardAsync`,
`PurchasePremiumAsync` (carrying `ScenarioId`/`NodeId`/`RunId`) are public;
the internal request overloads are gone.
- `BattlePassSession` now exposes the bound battle pass operations
(`GetProgressAsync`, `AddXpAsync(source, amount)`, `ClaimRewardAsync(level,
track)`, `PurchasePremiumAsync()` — crosses `onPremiumPurchase` on success),
mirroring the web SDK session.
- `BattlePassLevelSession.CompleteAsync`/`Complete` renamed to
`ClaimAsync`/`Claim`; new `Level` property reads the `levelNumber` node data
key.
- Unsupported scenario node types now fail the run (`OnScenarioFailed`)
instead of stalling silently.
- Scenario counter updates no longer read a continuation plan from the
response (the server stopped returning one); when the server reports the
objective completed, the node crosses `onComplete`.
### Fixed
- A failed scenario counter update no longer fails the run; the error is
logged and the node stays active.
## 0.2.0
### Added
- `QuestsService` (`client.Quests`) with `ListAsync` / `ClaimAsync`.
- `AuthService.LoginWithDeviceAsync(region, language, nickname?)` and
`AuthService.RefreshAsync()`; `AuthStateChanged` event
(`RudderAuthState.SignedIn` / `SignedOut`).
- Session pipeline: single-flight token refresh plus one transparent
retry-on-401 for every API call; failed refresh clears tokens and reports
`SignedOut`.
- `HttpClientTransport` — default `System.Net.Http.HttpClient`-based
transport. `RudderClientOptions.Transport` is now optional, as are
`TokenStore` (`InMemoryTokenStore`) and `DeviceIdProvider`
(`GuidDeviceIdProvider`).
- Typed exceptions: `RudderAuthException` (401), `RudderNotFoundException`
(404), `RudderRateLimitException` (429), `RudderNetworkException`
(network/timeout). All carry `RequestId` from the server error payload.
- `StorageService.ListAllAsync` and `UgcService.ListAllAsync`
(`IAsyncEnumerable<T>` cursor pagination helpers).
- `RudderLogLevel` enum; `IRudderLogger.Log` now takes a level.
- Package metadata (`Rudder.Core`, MIT) and XML documentation.
### Changed (breaking)
- Generated models moved to domain folders/namespaces
(`RudderSdk.Core.Models.<Domain>`); the flat `RudderSdk.Core.DTO`
namespace is gone. `Battlepass*``BattlePass*`, `SdkQuest``Quest`.
- `BattlepassService``BattlePassService`, `client.Battlepass`
`client.BattlePass`.
- `client.Scenarios``client.Scenario`.
- `ScenarioService.SendAsync``TriggerAsync`, now returning the started
`PlanRun`s.
- Scenario events reduced to the canonical set: `OnNotification`,
`OnStoreOffer`, `OnLeaderboard`, `OnConfigChanged`, `OnWait`, `OnQuest`,
`OnBattlePass`, `OnBattlePassLevel`, `OnScenarioCompleted`,
`OnScenarioFailed`. Legacy events (`OnShowNotification`, `OnShowStore`,
`OnQuestEvent`, `OnBattlepassEvent`, `OnLeaderboardEvent`, `OnNodeEvent`,
`OnNode`, `OnCompleted`, `OnStore`, `OnRemoteConfigOverride`,
`OnRunCompleted`, `OnRunFailed`) are removed, along with the
`Services/Scenarios/Legacy` folder.
- Session types renamed: `StoreSession``StoreOfferSession`
(`BuyAsync`/`Buy``PurchaseAsync`/`Purchase`),
`RemoteConfigOverrideSession``ConfigChangedSession`,
`BattlepassSession``BattlePassSession`,
`BattlepassLevelSession``BattlePassLevelSession`,
`ScenarioRunFailedEvent``ScenarioFailedEvent`.
- `StoresService.BuyAsync` → `PurchaseAsync(storeSlug, offerId,
idempotencyKey = null)`; a null key is replaced with a generated GUID.
- `InventoryService.GetAsync` returns `IReadOnlyList<PlayerInventoryItem>`.
- `StoresService.ListAsync` returns `IReadOnlyList<Store>`.
- `QuestsService.ListAsync` returns `IReadOnlyList<Quest>`.
- `UgcService.GetDownloadUrlAsync` returns non-null `string` and throws
`InvalidOperationException` when the server returns no URL.
- `BattlePassService` simple overloads (`AddXpAsync(long amount)`,
`ClaimRewardAsync(level, track)`, `GetProgressAsync()`,
`PurchasePremiumAsync(idempotencyKey?)`); the request-DTO overloads are
internal for the scenario runtime.
- `LeaderboardsService.GetRankingAsync`/`SubmitScoreAsync` are internal;
use the `FindBySlug(slug)` handle (`SubmitAsync`, `ListAsync`).
- `AuthService.LoginViaDeviceAsync` removed; use `LoginWithDeviceAsync`.
- `ScenarioService.Restore()` (sync-over-async) removed; use `RestoreAsync`.
- `RealtimeService.ConnectAsync` and `IRealtimeTransport.ConnectAsync` take
`TimeSpan` timeouts instead of `int timeoutSeconds`.
- `IRudderTransport.SendAsync` takes a `string? accessToken` instead of
`RequestOptions`; `RequestOptions` is removed and `EmptyResponse` is
internal.
- `RudderClient` getters `Options`, `Transport`, `TokenStore`,
`DeviceIdProvider` are internal.
- `RudderApiException.StatusCode` is `int` (was `long`).
- `IRudderLogger.Log(string)` → `Log(RudderLogLevel level, string message)`.
- Nullable reference types enabled (`<Nullable>enable</Nullable>`).
- Remote config cache now includes every config except an explicit
`"active": false` (a missing flag means active).