Player Data and Game Servers #
Game servers will need access to specific player data. Servers should not use the get all API to fetch player data. Implement operations that return the specific data needed by the game server.
Remember the Partner SDK includes all operations that have the SessionType.PARTNER in the operation’s annotation.
Example operation #
Below is a basic example of an operation that returns loadout data.
package documentation
import pragma.playerdata.Component
import pragma.playerdata.Context
import pragma.playerdata.Entity
import pragma.playerdata.FieldNumber
import pragma.playerdata.PlayerDataContentLibrary
import pragma.playerdata.PlayerDataOperation
import pragma.playerdata.PlayerDataRequest
import pragma.playerdata.PlayerDataResponse
import pragma.playerdata.PlayerDataSnapshot
import pragma.playerdata.PlayerDataSubService
import pragma.rpcs.SessionType
import pragma.types.SerializedName
import pragma.utils.ComponentId
class GetLoadoutRequest : PlayerDataRequest
data class GetLoadoutResponse(
val selectedCharacter: String,
val equippedGear: List<EquippedGear>,
) : PlayerDataResponse
data class EquippedGear(
val gearId: String,
val skinId: String,
)
@Suppress("unused") // used by reflection
class LoadoutSubService(contentLibrary: PlayerDataContentLibrary) : PlayerDataSubService(contentLibrary) {
// Define operations to fetch data game-servers require.
// The Partner SDK does not cache any player data.
@PlayerDataOperation(sessionTypes = [SessionType.PARTNER])
fun getLoadout(
@Suppress("UNUSED_PARAMETER") request: GetLoadoutRequest,
context: Context
): GetLoadoutResponse {
val inventory = context.snapshot.getGearInventory()
val loadout = context.snapshot.getOrCreateLoadout()
// filter and collect the data wanted by the game-server
val equippedGear = loadout.equippedGear.mapNotNull {
val component = inventory.getComponentById<Gear>(it) ?: return@mapNotNull null
EquippedGear(component.gearId, component.skinId)
}
return GetLoadoutResponse(loadout.heroSelected, equippedGear)
}
// entity to hold all of a player's gear items
private fun PlayerDataSnapshot.getGearInventory(): Entity {
return getOrCreateUniqueEntity("GearInventory")
}
// entity to store a player's loadout
private fun PlayerDataSnapshot.getOrCreateLoadout(): Loadout {
return getOrCreateUniqueEntity("Loadout") {
listOf(Loadout(mutableListOf(), ""))
}.getComponentsByType<Loadout>().single()
}
}
// example of component data
@SerializedName("1759966426")
data class Loadout(
@FieldNumber(1) var equippedGear: MutableList<ComponentId>,
@FieldNumber(2) var heroSelected: String,
) : Component
@SerializedName("1759966432")
data class Gear(
@FieldNumber(1) var gearId: String,
@FieldNumber(2) var minDamage: Int,
@FieldNumber(3) var maxDamage: Int,
@FieldNumber(4) var skinId: String,
) : Component
Call using the Unreal Partner SDK #
Below is an example of using the Unreal Partner SDK to call getLoadout.
void AUnicornGameMode::GetLoadout(const FString &PlayerId) {
// providing type - assign as private property on the GameMode etc ...
const Pragma::FServerPtr PartnerSdk;
PartnerSdk->PlayerDataService().Loadout().GetLoadout(
PlayerId,
FOnLoadoutGetLoadoutDelegate::CreateLambda(
[](const TPragmaResult<FPragma_PlayerData_GetLoadoutResponseProto>
&Result) {
if (Result.IsSuccessful()) {
const auto PlayersLoadout =
Result.Payload<FPragma_PlayerData_GetLoadoutResponseProto>();
UE_LOG(LogTemp, Display, TEXT("Current character from load: %s"),
*PlayersLoadout.SelectedCharacter);
} else {
// failure occurred ...
}
}));
}