feat: Add leaderboard and stats UI for minigames
- Implemented MinigameLeaderboardUIService to manage the leaderboard UI. - Created MinigameLeaderboardUISystem to handle UI updates. - Added methods in MinigameStatsService and MinigameStatsRepository for fetching top players and distinct dimension values. - Introduced new commands for accessing minigame stats in the command language. - Added tests for minigame interactions and ensured proper decoding of interaction fields. - Refactored MinigameRuntimeEffect to utilize MinigameActionContext for better context handling.
This commit is contained in:
@@ -2,14 +2,16 @@
|
||||
|
||||
A Hytale-native minigame extension for server-side minigame definitions, runtime state, and trigger-volume logic.
|
||||
|
||||
The mod mirrors Hytale's own asset and trigger systems instead of maintaining a separate minigame-only registry layer. Minigames are `MinigameDefinition` assets, trigger logic is registered as real `TriggerEffect` and `TriggerCondition` codec entries, and runtime events are dispatched on Hytale's event bus.
|
||||
The mod mirrors Hytale's own asset, trigger, and interaction systems instead of maintaining a separate minigame-only registry layer. Minigames are `MinigameDefinition` assets, trigger logic is registered as real `TriggerEffect` and `TriggerCondition` codec entries, item/entity/NPC actions can use real `Interaction` entries, and runtime events are dispatched on Hytale's event bus.
|
||||
|
||||
## Features
|
||||
|
||||
- Asset-driven minigame definitions in `Server/Minigames/`
|
||||
- Hytale Asset Editor support through `MinigameDefinition.CODEC`
|
||||
- Hytale trigger-volume integration through native `TriggerEffect` and `TriggerCondition` types
|
||||
- Hytale interaction integration through native `Interaction` types for item/entity/NPC use actions
|
||||
- Asset-backed `MinigameId` picker fields in the trigger-volume editor
|
||||
- Asset-backed minigame trigger-volume templates in `Server/MinigameVolumeTemplates/`
|
||||
- Runtime lifecycle commands for creating, enabling, starting, stopping, and resetting minigames
|
||||
- Multi-map runtime support using Hytale trigger-volume tags
|
||||
- Player, team, score, lives, counter, status, and phase runtime state
|
||||
@@ -67,6 +69,17 @@ Use normal Hytale trigger volumes for the area shape and interaction point, then
|
||||
|
||||
For multi-map minigames, tag volumes with `MinigameId=<id>`, `MapId=<map>`, optional `VariantId=<variant>`, and `MapRole=MainArena` on the primary arena volume. Team spawn volumes use `SpawnRole=TeamSpawn` and `TeamId=<team>`. `MapSelectionMode` controls whether a queued match uses votes or random selection.
|
||||
|
||||
To bootstrap common logic, spawn editable template volumes at your position:
|
||||
|
||||
```text
|
||||
/triggervolume minigametemplates
|
||||
/triggervolume minigametemplate core_lifecycle --MinigameId=My_Minigame --MapId=Arena01
|
||||
/triggervolume minigametemplate team_arena --MinigameId=Battle --MapId=Castle --VariantId=Night
|
||||
```
|
||||
|
||||
The UI remembers each builder's minigame/map variables. Both paths create normal Hytale
|
||||
trigger volumes with template tags replaced by the provided IDs.
|
||||
|
||||
Available condition types:
|
||||
|
||||
- `MinigamePhase`
|
||||
@@ -85,26 +98,30 @@ Available condition types:
|
||||
Available effect types:
|
||||
|
||||
- `StartMinigame`
|
||||
- `EndMinigame`
|
||||
- `ResetMinigame`
|
||||
- `SetMinigamePhase`
|
||||
- `ResetScores`
|
||||
- `ModifyScore`
|
||||
- `ModifyCounter`
|
||||
- `ModifyLives`
|
||||
- `SetPlayerStatus`
|
||||
- `SetPlayerLoadout`
|
||||
- `JoinMinigameQueue`
|
||||
- `LeaveMinigameQueue`
|
||||
- `VoteForMap`
|
||||
- `StartQueuedMinigame`
|
||||
- `SpawnItem`
|
||||
- `AwardKillScore`
|
||||
- `EndMinigame`
|
||||
- `ResetMinigame`
|
||||
- `SetMinigamePhase`
|
||||
- `ResetScores`
|
||||
- `ModifyPlayerScore`
|
||||
- `ModifyTeamScore`
|
||||
- `ModifyCounter`
|
||||
- `ModifyPlayerLives`
|
||||
- `SetPlayerStatus`
|
||||
- `SpawnNpc`
|
||||
- `MountPlayer`
|
||||
- `DismountPlayer`
|
||||
- `SetRound`
|
||||
- `StartTimer`
|
||||
- `StopTimer`
|
||||
- `SetSpawnPoint`
|
||||
- `RespawnPlayer`
|
||||
- `RespawnAllPlayers`
|
||||
- `SwapTeams`
|
||||
- `SendMinigameMessage`
|
||||
- `AssignTeam`
|
||||
- `SaveInventory`
|
||||
@@ -112,17 +129,122 @@ Available effect types:
|
||||
- `ClearInventory`
|
||||
- `SetObjectiveStatus`
|
||||
- `ModifyObjectiveProgress`
|
||||
- `AwardKillScore`
|
||||
- `PlaceBlocks`
|
||||
- `OpenMinigameQueueUI`
|
||||
- `StartPlayerTimer`
|
||||
- `StopPlayerTimer`
|
||||
|
||||
Fields named `MinigameId` use an editor dropdown backed by registered `MinigameDefinition` assets.
|
||||
|
||||
## Interaction Logic
|
||||
|
||||
Many minigame effects also have Hytale interaction counterparts. Interaction type IDs use the `Minigame` prefix plus the trigger effect ID, for example `MinigameJoinMinigameQueue`, `MinigameModifyScore`, and `MinigameOpenMinigameQueueUI`.
|
||||
|
||||
Interaction-backed minigame actions use Hytale root interaction cooldown and chaining fields instead of trigger-volume `Event`, `Interval`, and `Delay`. Common routing fields are `MinigameId`, optional `MapId`, optional `VariantId`, and optional `TeamId`.
|
||||
|
||||
Available interaction types:
|
||||
|
||||
- `MinigameStartMinigame`
|
||||
- `MinigameEndMinigame`
|
||||
- `MinigameResetMinigame`
|
||||
- `MinigameSetMinigamePhase`
|
||||
- `MinigameResetScores`
|
||||
- `MinigameModifyScore`
|
||||
- `MinigameModifyCounter`
|
||||
- `MinigameModifyLives`
|
||||
- `MinigameSetPlayerStatus`
|
||||
- `MinigameSetPlayerLoadout`
|
||||
- `MinigameJoinMinigameQueue`
|
||||
- `MinigameLeaveMinigameQueue`
|
||||
- `MinigameVoteForMap`
|
||||
- `MinigameStartQueuedMinigame`
|
||||
- `MinigameSetRound`
|
||||
- `MinigameStartTimer`
|
||||
- `MinigameStopTimer`
|
||||
- `MinigameSetSpawnPoint`
|
||||
- `MinigameRespawnPlayer`
|
||||
- `MinigameRespawnAllPlayers`
|
||||
- `MinigameSwapTeams`
|
||||
- `MinigameSendMinigameMessage`
|
||||
- `MinigameAssignTeam`
|
||||
- `MinigameSaveInventory`
|
||||
- `MinigameRestoreInventory`
|
||||
- `MinigameClearInventory`
|
||||
- `MinigameSetObjectiveStatus`
|
||||
- `MinigameModifyObjectiveProgress`
|
||||
- `MinigameOpenMinigameQueueUI`
|
||||
- `MinigameStartPlayerTimer`
|
||||
- `MinigameStopPlayerTimer`
|
||||
|
||||
Volume-only for now: `AwardKillScore`, `SpawnItem`, `SpawnNpc`, `MountPlayer`, `DismountPlayer`, and `PlaceBlocks`.
|
||||
|
||||
Inline item secondary-use example:
|
||||
|
||||
```json
|
||||
{
|
||||
"Interactions": {
|
||||
"Secondary": {
|
||||
"Interactions": [
|
||||
{
|
||||
"Type": "MinigameJoinMinigameQueue",
|
||||
"MinigameId": "Skywars"
|
||||
}
|
||||
],
|
||||
"Cooldown": {
|
||||
"Id": "join_skywars_queue",
|
||||
"Cooldown": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reusable assets:
|
||||
|
||||
`Server/Item/Interactions/join_skywars_queue.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"Type": "MinigameJoinMinigameQueue",
|
||||
"MinigameId": "Skywars"
|
||||
}
|
||||
```
|
||||
|
||||
`Server/Item/RootInteractions/join_skywars_queue_secondary.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"Interactions": [
|
||||
"join_skywars_queue"
|
||||
],
|
||||
"Cooldown": {
|
||||
"Id": "join_skywars_queue",
|
||||
"Cooldown": 1.0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then reference the root interaction from an item:
|
||||
|
||||
```json
|
||||
{
|
||||
"Interactions": {
|
||||
"Secondary": "join_skywars_queue_secondary"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```text
|
||||
core-minigames/
|
||||
|-- src/main/java/net/kewwbec/minigames/
|
||||
| |-- MinigameCorePlugin.java
|
||||
| |-- action/
|
||||
| |-- command/
|
||||
| |-- event/
|
||||
| |-- interaction/
|
||||
| |-- model/
|
||||
| |-- runtime/
|
||||
| |-- service/
|
||||
|
||||
Reference in New Issue
Block a user