From e9896cdce104a8c80420151c91f06bcdaaf929c5 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 14 May 2026 02:28:38 -0700 Subject: [PATCH] Add investor startup sequence --- .gitattributes | 1 + AGRARIAN_DEVELOPMENT_ROADMAP.md | 2 + Config/DefaultGame.ini | 5 ++ .../Maps/L_GroundZeroTerrain_Test.umap | 4 +- Content/Movies/AgrarianStudioIntro.mp4 | 3 + Scripts/PackageWindowsDevelopment.bat | 26 ++++++- Scripts/setup_ground_zero_demo_map.py | 7 ++ .../AgrarianGame/AgrarianDemoNoticeActor.cpp | 47 ++++++++++++ Source/AgrarianGame/AgrarianDemoNoticeActor.h | 42 +++++++++++ .../AgrarianGame/AgrarianDemoNoticeWidget.cpp | 74 +++++++++++++++++++ .../AgrarianGame/AgrarianDemoNoticeWidget.h | 47 ++++++++++++ Source/AgrarianGame/AgrarianGame.Build.cs | 3 +- 12 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 Content/Movies/AgrarianStudioIntro.mp4 create mode 100644 Source/AgrarianGame/AgrarianDemoNoticeActor.cpp create mode 100644 Source/AgrarianGame/AgrarianDemoNoticeActor.h create mode 100644 Source/AgrarianGame/AgrarianDemoNoticeWidget.cpp create mode 100644 Source/AgrarianGame/AgrarianDemoNoticeWidget.h diff --git a/.gitattributes b/.gitattributes index bdb591c..5a6b7ea 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,6 +5,7 @@ *.uexp filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text *.mp3 filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text *.bmp filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index 826ace2..6b404ff 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -317,6 +317,7 @@ Completed in version .01: - [x] Set the packaged investor demo default map to Ground Zero. - [x] Added first Agrarian Studio splash screen and investor demo legal notices. - [x] Built a Windows Development packaged demo and smoke-tested launch into Ground Zero. +- [x] Added startup movie and in-game beta demo notice with motto, version, and copyright language. Open version .01 tasks: @@ -345,6 +346,7 @@ Open version .01 tasks: - [x] Convert the extracted 1-meter DEM subset into an Unreal Landscape-ready heightmap and import plan. - [x] Import the Ground Zero R16 heightmap into an Unreal terrain test map. - [x] Package a Windows Development investor demo that starts on the Ground Zero map. +- [x] Add investor-facing startup sequence and beta/demo notice language. # Phase 1 - Foundational Survival MVP diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini index db1d3f2..03e87c3 100644 --- a/Config/DefaultGame.ini +++ b/Config/DefaultGame.ini @@ -12,6 +12,11 @@ CopyrightNotice=Copyright (c) 2026 Agrarian Studio. All rights reserved. LicensingTerms=Investor demo build. Not for public distribution. PrivacyPolicy=Internal prototype build; online services and telemetry policies are not final. +[/Script/MoviePlayer.MoviePlayerSettings] +bWaitForMoviesToComplete=True +bMoviesAreSkippable=True ++StartupMovies=AgrarianStudioIntro + [/Script/UnrealEd.ProjectPackagingSettings] BuildConfiguration=PPBC_Development ForDistribution=False diff --git a/Content/Agrarian/Maps/L_GroundZeroTerrain_Test.umap b/Content/Agrarian/Maps/L_GroundZeroTerrain_Test.umap index caecb85..7daeb77 100644 --- a/Content/Agrarian/Maps/L_GroundZeroTerrain_Test.umap +++ b/Content/Agrarian/Maps/L_GroundZeroTerrain_Test.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9eb6c3c9620f13c980d90fb955ce3a0758b35ca0a7c00331d0446bd342361e8a -size 7407234 +oid sha256:9a2ab0438daf46f9247bb01dc1adf80a5302e08ed7311e98061d8554242b239f +size 7408412 diff --git a/Content/Movies/AgrarianStudioIntro.mp4 b/Content/Movies/AgrarianStudioIntro.mp4 new file mode 100644 index 0000000..05f4d42 --- /dev/null +++ b/Content/Movies/AgrarianStudioIntro.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7a52070fa2764bc29a6f3f3052fdf18ac63d4f3ffba7fcc94df6dad7b732ef6 +size 63754 diff --git a/Scripts/PackageWindowsDevelopment.bat b/Scripts/PackageWindowsDevelopment.bat index 53346f6..d46f2ec 100644 --- a/Scripts/PackageWindowsDevelopment.bat +++ b/Scripts/PackageWindowsDevelopment.bat @@ -5,9 +5,11 @@ set "PROJECT_DIR=%~dp0.." set "PROJECT_FILE=%PROJECT_DIR%\AgrarianGame.uproject" set "UE_ROOT=C:\Program Files\Epic Games\UE_5.7" set "RUN_UAT=%UE_ROOT%\Engine\Build\BatchFiles\RunUAT.bat" +set "BUILD_BAT=%UE_ROOT%\Engine\Build\BatchFiles\Build.bat" set "ARCHIVE_DIR=%PROJECT_DIR%\Builds\WindowsDevelopment" set "LOG_DIR=%PROJECT_DIR%\Saved\BuildLogs" set "LOG_FILE=%LOG_DIR%\PackageWindowsDevelopment.log" +set "BUILD_LOG_FILE=%LOG_DIR%\PackageWindowsBuild.log" if not exist "%LOG_DIR%" mkdir "%LOG_DIR%" if not exist "%ARCHIVE_DIR%" mkdir "%ARCHIVE_DIR%" @@ -18,6 +20,12 @@ if not exist "%RUN_UAT%" ( exit /b 1 ) +if not exist "%BUILD_BAT%" ( + echo Unreal Engine 5.7 Build.bat was not found at: + echo %BUILD_BAT% + exit /b 1 +) + if not exist "%PROJECT_FILE%" ( echo Project file was not found at: echo %PROJECT_FILE% @@ -28,12 +36,28 @@ echo Packaging Agrarian Windows Development build... echo Archive: %ARCHIVE_DIR% echo Log: %LOG_FILE% +echo Building packaged targets without Unreal Build Accelerator... +( + call "%BUILD_BAT%" AgrarianGameEditor Win64 Development -Project="%PROJECT_FILE%" -WaitMutex -architecture=x64 -NoUBA + call "%BUILD_BAT%" AgrarianGame Win64 Development -Project="%PROJECT_FILE%" -WaitMutex -architecture=x64 -NoUBA +) > "%BUILD_LOG_FILE%" 2>&1 + +set "BUILD_EXIT_CODE=%ERRORLEVEL%" +type "%BUILD_LOG_FILE%" + +if not "%BUILD_EXIT_CODE%"=="0" ( + echo. + echo Target build failed with exit code %BUILD_EXIT_CODE%. + echo Log file: %BUILD_LOG_FILE% + exit /b %BUILD_EXIT_CODE% +) + call "%RUN_UAT%" BuildCookRun ^ -project="%PROJECT_FILE%" ^ -noP4 ^ -platform=Win64 ^ -clientconfig=Development ^ - -build ^ + -skipbuild ^ -cook ^ -stage ^ -pak ^ diff --git a/Scripts/setup_ground_zero_demo_map.py b/Scripts/setup_ground_zero_demo_map.py index 757568e..8ec659c 100644 --- a/Scripts/setup_ground_zero_demo_map.py +++ b/Scripts/setup_ground_zero_demo_map.py @@ -78,6 +78,13 @@ DEMO_ACTORS = [ "fixed_z": 4000.0, "rotation": unreal.Rotator(0.0, 0.0, 0.0), }, + { + "label": "AGR_DemoNoticeActor", + "class": unreal.AgrarianDemoNoticeActor, + "location_xy": unreal.Vector(-18500.0, -6400.0, 0.0), + "fixed_z": 1600.0, + "rotation": unreal.Rotator(0.0, 0.0, 0.0), + }, ] diff --git a/Source/AgrarianGame/AgrarianDemoNoticeActor.cpp b/Source/AgrarianGame/AgrarianDemoNoticeActor.cpp new file mode 100644 index 0000000..0e91217 --- /dev/null +++ b/Source/AgrarianGame/AgrarianDemoNoticeActor.cpp @@ -0,0 +1,47 @@ +// Copyright Pacificao. All Rights Reserved. + +#include "AgrarianDemoNoticeActor.h" + +#include "AgrarianDemoNoticeWidget.h" +#include "Blueprint/UserWidget.h" +#include "Engine/World.h" +#include "TimerManager.h" + +AAgrarianDemoNoticeActor::AAgrarianDemoNoticeActor() +{ + PrimaryActorTick.bCanEverTick = false; + NoticeWidgetClass = UAgrarianDemoNoticeWidget::StaticClass(); +} + +void AAgrarianDemoNoticeActor::BeginPlay() +{ + Super::BeginPlay(); + + APlayerController* PlayerController = GetWorld() ? GetWorld()->GetFirstPlayerController() : nullptr; + if (!PlayerController || !NoticeWidgetClass) + { + return; + } + + ActiveNoticeWidget = CreateWidget(PlayerController, NoticeWidgetClass); + if (!ActiveNoticeWidget) + { + return; + } + + ActiveNoticeWidget->VersionLabel = VersionLabel; + ActiveNoticeWidget->DemoNotice = DemoNotice; + ActiveNoticeWidget->AddToViewport(100); + + GetWorldTimerManager().SetTimer(RemoveNoticeTimerHandle, this, &AAgrarianDemoNoticeActor::RemoveNotice, NoticeDurationSeconds, false); +} + +void AAgrarianDemoNoticeActor::RemoveNotice() +{ + if (ActiveNoticeWidget) + { + ActiveNoticeWidget->RemoveFromParent(); + ActiveNoticeWidget = nullptr; + } +} + diff --git a/Source/AgrarianGame/AgrarianDemoNoticeActor.h b/Source/AgrarianGame/AgrarianDemoNoticeActor.h new file mode 100644 index 0000000..59a6976 --- /dev/null +++ b/Source/AgrarianGame/AgrarianDemoNoticeActor.h @@ -0,0 +1,42 @@ +// Copyright Pacificao. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "AgrarianDemoNoticeActor.generated.h" + +class UAgrarianDemoNoticeWidget; + +UCLASS() +class AGRARIANGAME_API AAgrarianDemoNoticeActor : public AActor +{ + GENERATED_BODY() + +public: + AAgrarianDemoNoticeActor(); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + TSubclassOf NoticeWidgetClass; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo", meta = (ClampMin = "1.0")) + float NoticeDurationSeconds = 9.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.01")); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution")); + +protected: + virtual void BeginPlay() override; + +private: + UPROPERTY() + TObjectPtr ActiveNoticeWidget; + + FTimerHandle RemoveNoticeTimerHandle; + + void RemoveNotice(); +}; + diff --git a/Source/AgrarianGame/AgrarianDemoNoticeWidget.cpp b/Source/AgrarianGame/AgrarianDemoNoticeWidget.cpp new file mode 100644 index 0000000..55c918f --- /dev/null +++ b/Source/AgrarianGame/AgrarianDemoNoticeWidget.cpp @@ -0,0 +1,74 @@ +// Copyright Pacificao. All Rights Reserved. + +#include "AgrarianDemoNoticeWidget.h" + +#include "Rendering/DrawElements.h" +#include "Styling/CoreStyle.h" + +int32 UAgrarianDemoNoticeWidget::NativePaint( + const FPaintArgs& Args, + const FGeometry& AllottedGeometry, + const FSlateRect& MyCullingRect, + FSlateWindowElementList& OutDrawElements, + int32 LayerId, + const FWidgetStyle& InWidgetStyle, + bool bParentEnabled) const +{ + LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); + + const FVector2D Size = AllottedGeometry.GetLocalSize(); + const float PanelWidth = FMath::Min(860.0f, Size.X - 96.0f); + const float PanelHeight = 210.0f; + const FVector2D PanelPosition((Size.X - PanelWidth) * 0.5f, 42.0f); + + FSlateDrawElement::MakeBox( + OutDrawElements, + ++LayerId, + AllottedGeometry.ToPaintGeometry(FVector2f(PanelWidth, PanelHeight), FSlateLayoutTransform(FVector2f(PanelPosition))), + FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")), + ESlateDrawEffect::None, + FLinearColor(0.02f, 0.03f, 0.025f, 0.82f)); + + FSlateDrawElement::MakeBox( + OutDrawElements, + ++LayerId, + AllottedGeometry.ToPaintGeometry(FVector2f(PanelWidth, 3.0f), FSlateLayoutTransform(FVector2f(PanelPosition))), + FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")), + ESlateDrawEffect::None, + FLinearColor(0.45f, 0.72f, 0.40f, 1.0f)); + + const FSlateFontInfo MottoFont = FCoreStyle::GetDefaultFontStyle("Bold", 30); + const FSlateFontInfo VersionFont = FCoreStyle::GetDefaultFontStyle("Regular", 18); + const FSlateFontInfo NoticeFont = FCoreStyle::GetDefaultFontStyle("Regular", 16); + + DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, Motto, PanelPosition.Y + 34.0f, MottoFont, FLinearColor(0.86f, 0.94f, 0.78f, 1.0f)); + DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, VersionLabel, PanelPosition.Y + 94.0f, VersionFont, FLinearColor(0.82f, 0.86f, 0.78f, 1.0f)); + DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, DemoNotice, PanelPosition.Y + 126.0f, NoticeFont, FLinearColor(0.78f, 0.82f, 0.75f, 1.0f)); + DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, CopyrightNotice, PanelPosition.Y + 158.0f, NoticeFont, FLinearColor(0.66f, 0.70f, 0.64f, 1.0f)); + + return LayerId; +} + +void UAgrarianDemoNoticeWidget::DrawCenteredText( + FSlateWindowElementList& OutDrawElements, + int32& LayerId, + const FGeometry& AllottedGeometry, + const FText& Text, + float Y, + const FSlateFontInfo& Font, + const FLinearColor& Color) const +{ + const FVector2D Size = AllottedGeometry.GetLocalSize(); + const FString TextString = Text.ToString(); + const float EstimatedWidth = FMath::Min(Size.X - 96.0f, static_cast(TextString.Len()) * Font.Size * 0.52f); + const FVector2D TextPosition((Size.X - EstimatedWidth) * 0.5f, Y); + + FSlateDrawElement::MakeText( + OutDrawElements, + ++LayerId, + AllottedGeometry.ToPaintGeometry(FVector2f(EstimatedWidth, Font.Size + 12.0f), FSlateLayoutTransform(FVector2f(TextPosition))), + Text, + Font, + ESlateDrawEffect::None, + Color); +} diff --git a/Source/AgrarianGame/AgrarianDemoNoticeWidget.h b/Source/AgrarianGame/AgrarianDemoNoticeWidget.h new file mode 100644 index 0000000..81fb681 --- /dev/null +++ b/Source/AgrarianGame/AgrarianDemoNoticeWidget.h @@ -0,0 +1,47 @@ +// Copyright Pacificao. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "AgrarianDemoNoticeWidget.generated.h" + +UCLASS() +class AGRARIANGAME_API UAgrarianDemoNoticeWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText Motto = FText::FromString(TEXT("What survives after you are gone?")); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.01")); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution")); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") + FText CopyrightNotice = FText::FromString(TEXT("Copyright (c) 2026 Agrarian Studio. All rights reserved.")); + +protected: + virtual int32 NativePaint( + const FPaintArgs& Args, + const FGeometry& AllottedGeometry, + const FSlateRect& MyCullingRect, + FSlateWindowElementList& OutDrawElements, + int32 LayerId, + const FWidgetStyle& InWidgetStyle, + bool bParentEnabled) const override; + +private: + void DrawCenteredText( + FSlateWindowElementList& OutDrawElements, + int32& LayerId, + const FGeometry& AllottedGeometry, + const FText& Text, + float Y, + const FSlateFontInfo& Font, + const FLinearColor& Color) const; +}; + diff --git a/Source/AgrarianGame/AgrarianGame.Build.cs b/Source/AgrarianGame/AgrarianGame.Build.cs index ff68c8f..a61f3d4 100644 --- a/Source/AgrarianGame/AgrarianGame.Build.cs +++ b/Source/AgrarianGame/AgrarianGame.Build.cs @@ -19,7 +19,8 @@ public class AgrarianGame : ModuleRules "GameplayStateTreeModule", "UMG", "Landscape", - "Slate" + "Slate", + "SlateCore" }); PrivateDependencyModuleNames.AddRange(new string[] { });