ChainSafe / ChainSafe/open-creator-rails.unity

Add AssetGroup for Multi-Asset In-Game Groupings (e.g. Tiered Pricing)

Open
#47 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

**What**

Add an `AssetGroup` MonoBehaviour (and `IAssetGroup` interface) that aggregates multiple `IAsset` instances representing the same in-game resource at different pricing tiers — for example, a monthly subscription asset and an annual subscription asset that both grant access to the same in-game content.

```csharp
+IsSubscriptionActive(string subscriberId) : UniTask
+IsSubscriptionExpired(string subscriberId) : UniTask
+IsSubscriberRevoked(string subscriberId) : UniTask
+GetSubscriptionExpiration(string subscriberId) : UniTask
```

Access checks use **OR logic** — a subscriber is considered active if they hold an active subscription on **any** asset in the group. Subscribing remains the responsibility of the individual `IAsset` instances; `AssetGroup` is access-check only.

**Why**

A common real-world pattern is offering the same in-game asset at multiple price points with different subscription durations (e.g. monthly at a lower price vs. annually at a discount). On-chain these are separate `Asset` contracts with separate `AssetId`s. Without `AssetGroup`, game code must manually query every tier and combine the results — boilerplate that belongs in the SDK.

**How**

1. **Create `IAssetGroup` interface** in `Runtime/`:
- `List Assets { get; }` — the grouped assets (tiers)
- `UniTask IsSubscriptionActive(string subscriberId)` — returns `true` if active on **any** asset
- `UniTask IsSubscriptionExpired(string subscriberId)` — returns `true` if expired (or not found) on **all** assets
- `UniTask IsSubscriberRevoked(string subscriberId)` — returns `true` if revoked on **all** assets
- `UniTask GetSubscriptionExpiration(string subscriberId)` — returns the **latest** `EndTime` across all active subscriptions in the group (i.e. the furthest future expiry)

2. **Create `AssetGroup` MonoBehaviour** implementing `IAssetGroup`:
- `[SerializeField] List _assets` — configured via Inspector, mirrors how `OpenCreatorRailsService` holds its `_assets` list
- Implement the interface methods by fanning out to each `IAsset` in `_assets` and combining results per the OR-logic rules above

3. **Register with `OpenCreatorRailsService`** (optional, for consideration): decide whether `AssetGroup` instances in the scene should be auto-discovered by the service (like `Asset` components are), or whether they are standalone and reference their constituent assets directly

4. **Add tests** in `AssetTests` (or a new `AssetGroupTests`) covering:
- Subscriber active on one tier → group returns active
- Subscriber active on no tiers → group returns inactive
- Subscriber revoked on one tier but active on another → group returns active
- `GetSubscriptionExpiration` returns the latest expiry across tiers

**Acceptance Criteria**

- [ ] `IAssetGroup` interface exists in the Runtime
- [ ] `AssetGroup` MonoBehaviour is configurable in the Inspector (drag-and-drop assets)
- [ ] OR-logic access checks: active on **any** asset → group is active
- [ ] `GetSubscriptionExpiration` returns the furthest future `EndTime` across the group
- [ ] `AssetGroup` does not expose `Subscribe` — subscription is delegated to individual `IAsset` instances
- [ ] Tests pass for the scenarios listed above

**Estimation**

**Dependencies**

None.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the existing IAsset and Asset APIs in Runtime, then inspect OpenCreatorRailsService and its _assets list pattern. Add IAssetGroup and the AssetGroup MonoBehaviour with Inspector-configured assets, and create AssetTests or AssetGroupTests for the listed active, inactive, revoked, and latest-expiration cases. Done means the acceptance criteria are met and the tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, unity
Domain
game-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.