Skip to content
24 changes: 23 additions & 1 deletion Scripts/Package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ PROJECT_ROOT=$("$SCRIPT_DIR"/FindProjectRoot.sh)
cd "$PROJECT_ROOT"
PROJECT_NAME=$(find . -maxdepth 1 -name "*.uproject" -exec basename {} .uproject \;)

# Check for low memory mode flag
LOW_MEMORY_MODE=false
for arg in "$@"; do
if [[ "$arg" == "--low-memory" ]]; then
LOW_MEMORY_MODE=true
fi
done

UNREAL_ENGINE_PATH=$("$SCRIPT_DIR"/FindUnreal.sh)

FIND_UPROJECT() {
Expand Down Expand Up @@ -134,8 +142,22 @@ if [ "$TEMPOROS_ENABLED" = "true" ]; then
PACKAGE_COMMAND="$PACKAGE_COMMAND -ScriptDir=\"$PROJECT_ROOT/Plugins/Tempo/TempoROS/Scripts\""
fi

# Add low memory options if requested
if [ "$LOW_MEMORY_MODE" = "true" ]; then
PACKAGE_COMMAND="$PACKAGE_COMMAND -CookPartialGC -NoXGE -AdditionalCookerOptions=\"-cookprocesscount=1\""
echo "Low memory mode enabled: single cook process, partial GC, no XGE"
fi

# Filter out our custom flags before passing to UAT
PASSTHROUGH_ARGS=()
for arg in "$@"; do
if [[ "$arg" != "--low-memory" ]]; then
PASSTHROUGH_ARGS+=("$arg")
fi
done

# Execute the command with any additional arguments
eval "$PACKAGE_COMMAND \"\$@\""
eval "$PACKAGE_COMMAND" "${PASSTHROUGH_ARGS[@]}"

# Copy cook metadata (including chunk manifests) to the package directory
if [[ "$TARGET_PLATFORM" = "Win64" ]]; then
Expand Down
34 changes: 34 additions & 0 deletions TempoCore/Source/TempoCore/Private/TempoCoreServiceSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@

#include "TempoCore/TempoCore.grpc.pb.h"

#include "AssetRegistry/AssetRegistryModule.h"
#include "GameFramework/GameMode.h"
#include "Kismet/GameplayStatics.h"

using TempoCoreService = TempoCore::TempoCoreService;
using TempoCoreAsyncService = TempoCore::TempoCoreService::AsyncService;
using LoadLevelRequest = TempoCore::LoadLevelRequest;
using CurrentLevelResponse = TempoCore::CurrentLevelResponse;
using GetAvailableLevelsRequest = TempoCore::GetAvailableLevelsRequest;
using AvailableLevelsResponse = TempoCore::AvailableLevelsResponse;
using SetMainViewportRenderEnabledRequest = TempoCore::SetMainViewportRenderEnabledRequest;
using SetControlModeRequest = TempoCore::SetControlModeRequest;

Expand All @@ -24,6 +27,7 @@ void UTempoCoreServiceSubsystem::RegisterScriptingServices(FTempoScriptingServer
SimpleRequestHandler(&TempoCoreAsyncService::RequestLoadLevel, &UTempoCoreServiceSubsystem::LoadLevel),
SimpleRequestHandler(&TempoCoreAsyncService::RequestFinishLoadingLevel, &UTempoCoreServiceSubsystem::FinishLoadingLevel),
SimpleRequestHandler(&TempoCoreAsyncService::RequestGetCurrentLevelName, &UTempoCoreServiceSubsystem::GetCurrentLevelName),
SimpleRequestHandler(&TempoCoreAsyncService::RequestGetAvailableLevels, &UTempoCoreServiceSubsystem::GetAvailableLevels),
SimpleRequestHandler(&TempoCoreAsyncService::RequestQuit, &UTempoCoreServiceSubsystem::Quit),
SimpleRequestHandler(&TempoCoreAsyncService::RequestSetMainViewportRenderEnabled, &UTempoCoreServiceSubsystem::SetRenderMainViewportEnabled),
SimpleRequestHandler(&TempoCoreAsyncService::RequestSetControlMode, &UTempoCoreServiceSubsystem::SetControlMode)
Expand Down Expand Up @@ -109,6 +113,36 @@ void UTempoCoreServiceSubsystem::GetCurrentLevelName(const TempoScripting::Empty
ResponseContinuation.ExecuteIfBound(Response, grpc::Status_OK);
}

void UTempoCoreServiceSubsystem::GetAvailableLevels(const GetAvailableLevelsRequest& Request, const TResponseDelegate<AvailableLevelsResponse>& ResponseContinuation) const
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really just gets any assets at a path. Not sure if we should add more filtering to truly get all levels or make it a more generic RPC

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean I think this RPC would be very useful but it shouldn't have a name specific to levels. We could have both and they could share a helper. Is it possible to find only levels? Does the umap extension help?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make it a more generic RPC, it does look like there's a way to filter by levels and add a more specific RPC, or we can filter client side maybe by .umap

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think two RPCs, one for levels and one for all non-level assets would be best. I don't really think of levels as "assets"

{
AvailableLevelsResponse Response;

IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();

// Use provided search path or default to /Game/
FString SearchPath = UTF8_TO_TCHAR(Request.search_path().c_str());
if (SearchPath.IsEmpty())
{
SearchPath = TEXT("/Game");
}

FARFilter Filter;
Filter.ClassPaths.Add(UWorld::StaticClass()->GetClassPathName());
Filter.PackagePaths.Add(*SearchPath);
Filter.bRecursivePaths = true;

TArray<FAssetData> AssetList;
AssetRegistry.GetAssets(Filter, AssetList);

for (const FAssetData& Asset : AssetList)
{
FString LevelPath = Asset.PackageName.ToString();
Response.add_levels(TCHAR_TO_UTF8(*LevelPath));
}

ResponseContinuation.ExecuteIfBound(Response, grpc::Status_OK);
}

void UTempoCoreServiceSubsystem::Quit(const TempoScripting::Empty& Request, const TResponseDelegate<TempoScripting::Empty>& ResponseContinuation) const
{
RequestEngineExit(TEXT("TempoCore API received quit request"));
Expand Down
10 changes: 10 additions & 0 deletions TempoCore/Source/TempoCore/Public/TempoCore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ message CurrentLevelResponse {
string level = 1;
}

message GetAvailableLevelsRequest {
string search_path = 1; // e.g. "/Game/Maps" - empty string searches /Game/
}

message AvailableLevelsResponse {
repeated string levels = 1;
}

message SetMainViewportRenderEnabledRequest {
bool enabled = 1;
}
Expand All @@ -36,6 +44,8 @@ service TempoCoreService {

rpc GetCurrentLevelName(TempoScripting.Empty) returns (CurrentLevelResponse);

rpc GetAvailableLevels(GetAvailableLevelsRequest) returns (AvailableLevelsResponse);

rpc Quit(TempoScripting.Empty) returns (TempoScripting.Empty);

rpc SetMainViewportRenderEnabled(SetMainViewportRenderEnabledRequest) returns (TempoScripting.Empty);
Expand Down
4 changes: 4 additions & 0 deletions TempoCore/Source/TempoCore/Public/TempoCoreServiceSubsystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace TempoCore
{
class LoadLevelRequest;
class CurrentLevelResponse;
class GetAvailableLevelsRequest;
class AvailableLevelsResponse;
class SetMainViewportRenderEnabledRequest;
class SetControlModeRequest;
}
Expand All @@ -41,6 +43,8 @@ class TEMPOCORE_API UTempoCoreServiceSubsystem : public UTempoGameInstanceSubsys

void GetCurrentLevelName(const TempoScripting::Empty& Request, const TResponseDelegate<TempoCore::CurrentLevelResponse>& ResponseContinuation);

void GetAvailableLevels(const TempoCore::GetAvailableLevelsRequest& Request, const TResponseDelegate<TempoCore::AvailableLevelsResponse>& ResponseContinuation) const;

void Quit(const TempoScripting::Empty& Request, const TResponseDelegate<TempoScripting::Empty>& ResponseContinuation) const;

void SetDeferBeginPlay(bool bDeferBeginPlayIn) { bDeferBeginPlay = bDeferBeginPlayIn; }
Expand Down
Loading