ChainSafe / ChainSafe/open-creator-rails.unity
Add AssetGroup for Multi-Asset In-Game Groupings (e.g. Tiered Pricing)
- 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