announcements

Announcements (Timed Notices)

Operator-posted timed notices every player sees - "Maintenance at 18:00" for the next 30 minutes. An operator posts one from the admin API (announce / announce-clear / announcements) with its text and an end time; everyone signed in gets it pushed, every player who signs in before it ends gets it at sign-in, and clearing it takes it down everywhere. The client hides each notice on time by itself; the popup is the game's. No player verb exists, so a notice cannot be forged. Held in memory on each node: a restart drops them.

Category Social Seams 1 Services 1 Options 1 Wire ids 2 Unity types 1
Server
services.AddCrossplayAnnouncements();
Unity package
com.crossplay.announcements
Depends on
core

Providers you can swap 1

Infrastructure seams. Crossplay ships a working implementation of each — replacing one changes where data lives or how it moves, never a game rule.

IAnnouncementClock provider

The clock notices end by (a seam so tests control time).

  • long UtcNowMs { get; }

    Now, unix ms UTC.

Services you call 1

Crossplay implements these. Resolve them from DI and call them from your own systems.

IAnnouncementService

Operator-posted timed notices. Game code may post too (it is trusted); players never can - there is no wire verb.

  • IReadOnlyList<ActiveAnnouncement> Active()

    The notices up now, oldest first.

  • bool Clear(long id)

    Takes a notice down and tells everyone signed in. False when no such notice is up.

  • int ClearAll()

    Takes every notice down. Returns how many were up.

  • bool TryPost(string text, long endsAtUtcMs, out long id, out string error)

    Posts a notice that ends at endsAtUtcMs and pushes it to everyone signed in. False with a reason when the text is empty, too long or holds control characters, the end is past or beyond MaxDurationMinutes, or MaxActive are up.

Configuration 1

Every tunable lives in an options object — there are no magic numbers to hunt for.

AnnouncementsOptions

Tuning for the Announcements piece (Crossplay:Announcements).

  • int MaxActive { get; set; }

    How many notices may be up at once.

  • double MaxDurationMinutes { get; set; }

    The longest a notice may stay up, in minutes (default a week).

  • int MaxTextLength { get; set; }

    The longest notice text, in characters.

Wire messages 2

The protocol this piece speaks. Ids are allocated per piece so they can never collide.

8101 Announcement

Server -> client: an operator's timed notice ("Maintenance at 18:00"). Sent to everyone signed in when it is posted, and again to each player who signs in before it ends, so a late arrival still sees it. The text is the operator's, shown as-is. There is no client -> server counterpart: a player cannot post or forge a notice.

8102 AnnouncementCleared

Server -> client: a notice was cleared before its end time. One that simply ends sends nothing.

Unity services you inject 1

Crossplay binds these in the client context. Inject and call them from your own MonoBehaviours and presenters.

IAnnouncementClient

Client SDK for Announcements - the operator's timed notices ("Maintenance at 18:00"). The server pushes each one when it is posted and again at sign-in while it is up; this client keeps the ones that are up and ends each on time by itself, timed from the server's "time left" so a wrong device clock cannot keep a notice up or hide it early. The text is the operator's, shown as-is; the popup is the game's. Pure SDK, no UI, no verbs - a player cannot post a notice.

  • event Action<Announcement> Shown

    A notice went up (or arrived at sign-in). Raised once per notice, on the main thread.

  • event Action<long> Cleared

    A notice ended: the operator cleared it, or its time ran out. Carries its Id.

  • IReadOnlyList<Announcement> Active

    The notices up now, oldest first.