---
title: "Deliver shared game files"
description: "Read files distributed to every player of the game."
seo:
  noindex: true
---

{/* Copyright (c) 2026 Betide Studio. All Rights Reserved. */}

Publish shared files through a provider that supports title storage, such as [EOS](/integrations/eos/platform-services). Choose it in the **Platform** policy. Title files are read-only game content; use [cloud saves](/crossplay/cloud-saves) for player uploads.

## List published files

**Blueprint**

<BlueprintViewer title="List published files" src="/blueprints/crossplay-list-title-files.txt" />

**C++**

Game module dependencies: `UCIKCore`, `BetideCore`.

```cpp
#include "Engine/GameInstance.h"
#include "Platform/UCIKPlatformSubsystem.h"
#include "UCIKCore.h"

void ListGameFiles(UGameInstance &GameInstance)
{
    auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>();
    if (!Service)
        return;

    TArray<FString> Tags;
    Service->EnumerateTitleFiles(
        Tags, FBetideCallback<TArray<FUCIK_TitleFileMetadata>>::CreateWeakLambda(
                  &GameInstance, [](const TBetideResult<TArray<FUCIK_TitleFileMetadata>> &Result) {
                      if (!Result.bOk)
                      {
                          UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
                          return;
                      }
                      UE_LOG(LogUCIK, Log, TEXT("Published files: %d"), Result.GetValue().Num());
                  }));
}
```
## Download a file

**Blueprint**

<BlueprintViewer title="Download a file" src="/blueprints/crossplay-read-title-file.txt" />

**C++**

Game module dependencies: `UCIKCore`, `BetideCore`.

```cpp
#include "Engine/GameInstance.h"
#include "Platform/UCIKPlatformSubsystem.h"
#include "UCIKCore.h"

void ReadGameConfig(UGameInstance &GameInstance)
{
    auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>();
    if (!Service)
        return;

    Service->ReadTitleFile(
        TEXT("game-config.json"),
        FBetideCallback<FUCIK_TitleFile>::CreateWeakLambda(
            &GameInstance, [](const TBetideResult<FUCIK_TitleFile> &Result) {
                if (!Result.bOk)
                {
                    UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
                    return;
                }
                UE_LOG(LogUCIK, Log, TEXT("Config bytes: %d"), Result.GetValue().Data.Num());
            }));
}
```

The first configured provider with title-file support supplies the result. A file name must match the published file exactly. Keep a local default for offline startup and reject invalid or incompatible content before applying it.

## Read a JSON configuration

**Blueprint**

<BlueprintViewer title="Read a JSON configuration" src="/blueprints/crossplay-parse-title-config.txt" />

**C++**

Add `UCIKNodes` to your game module dependencies. This accepts the same config formats as the Blueprint example.

```cpp
#include "Platform/UCIK_PlatformNodes.h"

bool ReadPlayerLimit(const FUCIK_TitleFile &File, int32 &OutLimit)
{
    const TMap<FString, FString> Config = UUCIK_PlatformLibrary::ParseTitleFileAsConfig(File);
    const FString *Value = Config.Find(TEXT("maxPlayers"));
    if (!Value || !Value->IsNumeric())
        return false;
    const float Limit = FCString::Atof(**Value);
    if (!FMath::IsFinite(Limit) || Limit < 1 || Limit > 64 || Limit != FMath::FloorToFloat(Limit))
        return false;
    OutLimit = static_cast<int32>(Limit);
    return true;
}
```

The Blueprint parser accepts flat JSON values or `key=value` text and returns strings. Nested JSON objects and arrays are omitted. Validate values before replacing active configuration.
