-
Notifications
You must be signed in to change notification settings - Fork 3
Home
The ArenaService is responsible for managing Arena-related logic outside the Nine Chronicles blockchain. It is built on the core battle logic defined in Battle.cs and handles everything from matchmaking and ticket management to ranking updates and participant tracking.
The database models are defined in the ArenaService.Shared/Models directory.
ArenaService uses PostgreSQL as its primary data store.
Below is the current schema diagram:

Redis is used to cache frequently accessed data, such as:
- The current block index from the Nine Chronicles chain
- Ranking boards (for both current and next rounds)
- Additional Arena metadata
ArenaService organizes gameplay into Seasons and Rounds, defined in corresponding database tables.
Each Season covers a specific block range.
Within each season, Rounds are defined with a fixed block interval. Each round resets tickets and determines matchmaking periods.
The CacheBlockTipWorker periodically checks the Nine Chronicles chain to determine the current block height and stores it in Redis. It also tracks the active season and round and updates them in cache accordingly.
Whenever a new round is detected, tickets are reset and the active ranking board switches to match the new round.
To participate in Arena battles, users must authenticate with a JWT signed using their Nine Chronicles private key. This token is verified by the ES256KAuthenticationHandler and includes the following claims:
- Avatar address
- Nine Chronicles address
- Expiration time
- Other metadata
(See this discussion for more details.)
The client generates the JWT and registers the user via the UserController endpoint.
This registration is performed every time the official client is launched to ensure up-to-date user records.
When a user fetches potential opponents, they are automatically added to the current season’s participants table via the ParticipateService.
To start a battle, the client must first obtain a battle token from ArenaService by calling the /battle/token endpoint.
This token is then embedded in the memo field of a Battle action and submitted to the Nine Chronicles blockchain.
sequenceDiagram
participant User
participant Client
participant RestAPI
participant Worker
participant 9cChain
participant Database
User ->> Client: Requests battle
Client ->> RestAPI: Requests battle token
RestAPI ->> Client: Returns battle token
Client ->> 9cChain: Sends Battle Action with token
Client ->> RestAPI: Sends Transaction ID
loop Polling
Client ->> RestAPI: Checks battle status
RestAPI -->> Client: In progress (retry after n seconds)
end
RestAPI ->> Worker: Sends Transaction ID
Worker ->> 9cChain: Monitors transaction
9cChain -->> Worker: Confirms block and provides result
Worker ->> Database: Stores battle result
Database -->> RestAPI: Battle result saved
RestAPI ->> Client: Returns battle result
Client ->> User: Displays battle result
ArenaService monitors this transaction using the BattleTxTracker.
Once the transaction is confirmed, the tracker validates the token (e.g., checks for reuse, matching signer, etc.) and applies the score update.
While battles ultimately update the score field in the database, Redis SortedSets are used to manage real-time rankings efficiently.
In Nine Chronicles Arena, if round 1 is currently active, it is used for opponent selection only, and its ranking remains unchanged.
All score updates are applied to round 2 instead.
Redis holds ranking boards for both the current and next round, allowing the system to prepare in advance.
This logic is implemented in the BattleProcessor, where score changes are applied only to the next round's board.
To ensure ranking boards are available when a new round or season starts, two workers run periodically to preload and manage them:
- PrepareRankingWorker: Prepares boards for upcoming rounds/seasons
- RankingCopyWorker: Copies ranking data between rounds when needed
These workers help maintain a smooth Arena experience without downtime or delays during round transitions.