Add pause save exit settings shell
This commit is contained in:
@@ -950,6 +950,7 @@ Required order:
|
||||
- [x] Replace or upgrade grasses, shrubs, and trees with believable coastal-scrub vegetation assets, density, color variation, scale variation, and LOD/performance limits. Added native generated coastal oak, coyote brush, and dry grass clump mesh assets under `/Game/Agrarian/Environment/Vegetation`, switched the Ground Zero foliage patch off engine basic shapes, rebuilt foliage materials with per-instance color variation, preserved investor-facing density and scale variation, added explicit HISM cull/shadow performance limits, and extended verifiers so basic-shape vegetation or missing cull limits fail.
|
||||
- [x] Add the Asset acquisition and ingest pipeline before pulling more visuals: created approved staging folders, added `Docs/Art/AssetLicenses.md`, documented the pipeline in `Docs/Art/AgrarianAssetPipeline.md`, added `Scripts/verify_asset_pipeline_policy.py`, defaulted to Fab/free, Quixel, CC0/public-domain, team-created, or Nathan-supplied assets only, rejected random scraped internet assets, and prioritized trees, shrubs, grass, water, rocks, character bodies/outfits, and old abandoned equipment being reclaimed by nature.
|
||||
- [x] Add the Ground Zero asset acquisition queue for the investor visual pass: documented free-only Fab candidates for shrubs, Mediterranean/coastal plants, grass, rocks/water-support props, and rural/reclaimed set dressing in `Docs/Art/GroundZeroAssetAcquisitionQueue.md`; added `Scripts/verify_ground_zero_asset_queue.py`; tied every candidate to the license register and staging workflow.
|
||||
- [x] Add stable MVP pause menu save/exit/settings shell: Resume, Save Game, Settings, Save & Exit, and Quit Without Saving now have separate player-facing actions, keyboard shortcuts, and verifier coverage while deeper settings stay roadmapped.
|
||||
- [ ] Replace or upgrade freshwater visuals with readable water surface, edge treatment, bank dressing, reflection/roughness tuning, and collectability cues.
|
||||
- [ ] Replace or upgrade character bodies and clothing so selected characters read as realistic near-future post-collapse frontier people rather than template mannequins or proxy stacks.
|
||||
- [ ] Replace or upgrade resource objects so wood, stone, fiber, edible plants, pickups, and gathered items look like world objects rather than debug primitives.
|
||||
@@ -1058,6 +1059,18 @@ Required order:
|
||||
- [ ] Add early business knowledge for bookkeeping, inventory, profit/loss, fair trade, basic credit, risk, and customer trust.
|
||||
- [ ] Add simple workshop/business ownership rules for homestead-scale production.
|
||||
|
||||
## 0.2.F1 Player Options And Settings
|
||||
|
||||
- [ ] Define the settings persistence model so options survive save/load, packaged demos, and future multiplayer profile storage.
|
||||
- [ ] Add preferred units for metric/imperial distance, weight, temperature, speed, volume, and field-size display.
|
||||
- [ ] Add controls remapping UI for keyboard, mouse, and gamepad while preserving sane defaults for movement, sprint, crouch, prone, interact, menus, and camera.
|
||||
- [ ] Add gameplay settings for autosave cadence, UI scale, hints, camera behavior, interaction prompts, and accessibility-friendly timing.
|
||||
- [ ] Add graphics and hardware settings for quality presets, resolution/window mode, frame cap, foliage density, shadows, water, post-process, ray tracing optional toggles, and reset-to-safe defaults.
|
||||
- [ ] Add audio settings for master, music, effects, ambient, voice, and cinematic volume.
|
||||
- [ ] Add accessibility settings for subtitles, color/contrast, text scale, hold-versus-toggle interactions, motion comfort, and input assistance.
|
||||
- [ ] Add account/server preferences for default server, last-used address, privacy-safe telemetry choice, and multiplayer connection display.
|
||||
- [ ] Add verifier coverage for settings save/load, default migration, reset-to-default behavior, and packaged-demo menu access.
|
||||
|
||||
## 0.2.G Homesteading Knowledge Progression
|
||||
|
||||
- [ ] Define early profession paths: farmer, herder, carpenter, mason, cook, medic, hunter, fisher, trapper, trader, and scout.
|
||||
|
||||
@@ -13,15 +13,29 @@ EXPECTED = {
|
||||
"AgrarianMvpFrontendWidget.h": [
|
||||
"ConfirmActiveScreen",
|
||||
"BackFromActiveScreen",
|
||||
"SaveGame",
|
||||
"SaveAndQuit",
|
||||
"QuitWithoutSaving",
|
||||
"Settings",
|
||||
"GameSaved",
|
||||
],
|
||||
"AgrarianMvpFrontendWidget.cpp": [
|
||||
"UButton::StaticClass()",
|
||||
"HandleMaleCharacterClicked",
|
||||
"HandleFemaleCharacterClicked",
|
||||
"OnClicked.AddDynamic",
|
||||
"Save & Quit",
|
||||
"Save Game",
|
||||
"Settings",
|
||||
"Save & Exit",
|
||||
"Quit Without Saving",
|
||||
"Saving World",
|
||||
"Game Saved",
|
||||
"Player Options",
|
||||
"HandleSaveGameClicked",
|
||||
"HandleSettingsClicked",
|
||||
"HandleQuitWithoutSavingClicked",
|
||||
"ExecuteSaveGame",
|
||||
"ExecuteQuitWithoutSaving",
|
||||
"ConsoleCommand(TEXT(\"AgrarianSaveWorld\"))",
|
||||
"ConsoleCommand(TEXT(\"quit\"))",
|
||||
"AAgrarianGamePlayerController* AgrarianPlayerController",
|
||||
|
||||
@@ -23,8 +23,12 @@ def main() -> None:
|
||||
roadmap = ROADMAP.read_text(encoding="utf-8")
|
||||
|
||||
for token in (
|
||||
"Settings",
|
||||
"GameSaved",
|
||||
"SavingAndQuit",
|
||||
"SaveGame",
|
||||
"ExecuteSaveAndQuit",
|
||||
"QuitWithoutSaving",
|
||||
):
|
||||
require(token in header, f"missing segmented flow declaration: {token}")
|
||||
|
||||
@@ -34,11 +38,20 @@ def main() -> None:
|
||||
"Loading Segment",
|
||||
"Pause Menu",
|
||||
"Gameplay is paused while this menu is active.",
|
||||
"Save Game",
|
||||
"Settings",
|
||||
"Quit Without Saving",
|
||||
"Game Saved",
|
||||
"Player Options",
|
||||
"Saving World",
|
||||
"Writing the current world state",
|
||||
"SetActiveScreen(EAgrarianMvpFrontendScreen::GameSaved)",
|
||||
"SetActiveScreen(EAgrarianMvpFrontendScreen::Settings)",
|
||||
"SetActiveScreen(EAgrarianMvpFrontendScreen::SavingAndQuit)",
|
||||
"GetTimerManager().SetTimer",
|
||||
"ExecuteSaveGame",
|
||||
"ExecuteSaveAndQuit",
|
||||
"ExecuteQuitWithoutSaving",
|
||||
"ConsoleCommand(TEXT(\"AgrarianSaveWorld\"))",
|
||||
"ConsoleCommand(TEXT(\"quit\"))",
|
||||
):
|
||||
|
||||
@@ -87,6 +87,33 @@ FReply UAgrarianMvpFrontendWidget::NativeOnKeyDown(const FGeometry& InGeometry,
|
||||
SaveAndQuit();
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (Key == EKeys::S)
|
||||
{
|
||||
SaveGame();
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (Key == EKeys::O)
|
||||
{
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::Settings);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (Key == EKeys::X)
|
||||
{
|
||||
QuitWithoutSaving();
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::Settings || ActiveScreen == EAgrarianMvpFrontendScreen::GameSaved)
|
||||
{
|
||||
const FKey Key = InKeyEvent.GetKey();
|
||||
if (Key == EKeys::Escape || Key == EKeys::BackSpace || Key == EKeys::Enter || Key == EKeys::SpaceBar)
|
||||
{
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::MainMenu);
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::SavingAndQuit)
|
||||
{
|
||||
@@ -147,6 +174,17 @@ void UAgrarianMvpFrontendWidget::SaveAndQuit()
|
||||
ExecuteSaveAndQuit();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::SaveGame()
|
||||
{
|
||||
ExecuteSaveGame();
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::GameSaved);
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::QuitWithoutSaving()
|
||||
{
|
||||
ExecuteQuitWithoutSaving();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ExecuteSaveAndQuit()
|
||||
{
|
||||
if (APlayerController* PlayerController = GetOwningPlayer())
|
||||
@@ -156,6 +194,22 @@ void UAgrarianMvpFrontendWidget::ExecuteSaveAndQuit()
|
||||
}
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ExecuteSaveGame()
|
||||
{
|
||||
if (APlayerController* PlayerController = GetOwningPlayer())
|
||||
{
|
||||
PlayerController->ConsoleCommand(TEXT("AgrarianSaveWorld"));
|
||||
}
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ExecuteQuitWithoutSaving()
|
||||
{
|
||||
if (APlayerController* PlayerController = GetOwningPlayer())
|
||||
{
|
||||
PlayerController->ConsoleCommand(TEXT("quit"));
|
||||
}
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
|
||||
{
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
|
||||
@@ -181,6 +235,12 @@ void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::Settings || ActiveScreen == EAgrarianMvpFrontendScreen::GameSaved)
|
||||
{
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::MainMenu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
|
||||
{
|
||||
CompleteFrontendFlow();
|
||||
@@ -200,6 +260,11 @@ void UAgrarianMvpFrontendWidget::ReturnFromActiveScreen()
|
||||
{
|
||||
CompleteFrontendFlow();
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::Settings || ActiveScreen == EAgrarianMvpFrontendScreen::GameSaved)
|
||||
{
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::MainMenu);
|
||||
}
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::CompleteFrontendFlow()
|
||||
@@ -274,13 +339,23 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
|
||||
{
|
||||
AddText(Panel, FText::FromString(TEXT("Pause Menu")), FMath::RoundToInt(20.0f * Scale), true, AccentColor, 6.0f * Scale);
|
||||
AddText(Panel, MainMenuTitle, FMath::RoundToInt(54.0f * Scale), true, TextColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Gameplay is paused while this menu is active.")), FMath::RoundToInt(22.0f * Scale), false, MutedTextColor, 72.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Gameplay is paused while this menu is active.")), FMath::RoundToInt(22.0f * Scale), false, MutedTextColor, 34.0f * Scale);
|
||||
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Resume")), ButtonColor, ButtonHoverColor, 16.0f * Scale);
|
||||
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
|
||||
|
||||
UButton* QuitButton = AddButton(Panel, FText::FromString(TEXT("Save & Quit")), QuitButtonColor, FLinearColor(0.58f, 0.28f, 0.22f, 1.0f), 34.0f * Scale);
|
||||
UButton* SaveButton = AddButton(Panel, FText::FromString(TEXT("Save Game")), SecondaryButtonColor, ButtonHoverColor, 12.0f * Scale);
|
||||
SaveButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleSaveGameClicked);
|
||||
|
||||
UButton* SettingsButton = AddButton(Panel, FText::FromString(TEXT("Settings")), SecondaryButtonColor, ButtonHoverColor, 12.0f * Scale);
|
||||
SettingsButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleSettingsClicked);
|
||||
|
||||
UButton* QuitButton = AddButton(Panel, FText::FromString(TEXT("Save & Exit")), QuitButtonColor, FLinearColor(0.58f, 0.28f, 0.22f, 1.0f), 12.0f * Scale);
|
||||
QuitButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked);
|
||||
AddText(Panel, FText::FromString(TEXT("Escape opens this menu. Save & Quit writes the current world save before closing.")), FMath::RoundToInt(16.0f * Scale), false, MutedTextColor, 0.0f);
|
||||
|
||||
UButton* QuitWithoutSavingButton = AddButton(Panel, FText::FromString(TEXT("Quit Without Saving")), SecondaryButtonColor, FLinearColor(0.46f, 0.20f, 0.16f, 1.0f), 28.0f * Scale);
|
||||
QuitWithoutSavingButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleQuitWithoutSavingClicked);
|
||||
|
||||
AddText(Panel, FText::FromString(TEXT("Esc resumes. S saves. O opens settings. Q saves and exits. X exits without saving.")), FMath::RoundToInt(16.0f * Scale), false, MutedTextColor, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -390,6 +465,26 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::GameSaved)
|
||||
{
|
||||
AddText(Panel, FText::FromString(TEXT("Game Saved")), FMath::RoundToInt(20.0f * Scale), true, AccentColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("World state saved")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Return to the pause menu before resuming or exiting.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 28.0f * Scale);
|
||||
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Back to Pause Menu")), ButtonColor, ButtonHoverColor, 0.0f);
|
||||
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleBackClicked);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::Settings)
|
||||
{
|
||||
AddText(Panel, FText::FromString(TEXT("Settings")), FMath::RoundToInt(20.0f * Scale), true, AccentColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Player Options")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Interface scale and high contrast are available now through tester commands. Units, controls, hardware, audio, and accessibility options are queued for the settings roadmap.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 28.0f * Scale);
|
||||
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Back to Pause Menu")), ButtonColor, ButtonHoverColor, 0.0f);
|
||||
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleBackClicked);
|
||||
return;
|
||||
}
|
||||
|
||||
AddText(Panel, FText::FromString(TEXT("Loading Segment")), FMath::RoundToInt(18.0f * Scale), true, AccentColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Preparing Ground Zero")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Loading terrain, weather, survival state, and server session data.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 70.0f * Scale);
|
||||
@@ -485,6 +580,30 @@ void UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked()
|
||||
});
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleSaveGameClicked()
|
||||
{
|
||||
DeferFrontendAction([this]()
|
||||
{
|
||||
SaveGame();
|
||||
});
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleSettingsClicked()
|
||||
{
|
||||
DeferFrontendAction([this]()
|
||||
{
|
||||
SetActiveScreen(EAgrarianMvpFrontendScreen::Settings);
|
||||
});
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleQuitWithoutSavingClicked()
|
||||
{
|
||||
DeferFrontendAction([this]()
|
||||
{
|
||||
QuitWithoutSaving();
|
||||
});
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked()
|
||||
{
|
||||
DeferFrontendAction([this]()
|
||||
|
||||
@@ -17,6 +17,8 @@ enum class EAgrarianMvpFrontendScreen : uint8
|
||||
CharacterSelection,
|
||||
JoinServer,
|
||||
Loading,
|
||||
Settings,
|
||||
GameSaved,
|
||||
SavingAndQuit
|
||||
};
|
||||
|
||||
@@ -75,9 +77,15 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|MVP UI")
|
||||
void BackFromActiveScreen();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|MVP UI")
|
||||
void SaveGame();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|MVP UI")
|
||||
void SaveAndQuit();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|MVP UI")
|
||||
void QuitWithoutSaving();
|
||||
|
||||
protected:
|
||||
virtual void NativeConstruct() override;
|
||||
|
||||
@@ -96,6 +104,8 @@ private:
|
||||
|
||||
UFUNCTION()
|
||||
void ExecuteSaveAndQuit();
|
||||
void ExecuteSaveGame();
|
||||
void ExecuteQuitWithoutSaving();
|
||||
|
||||
UFUNCTION()
|
||||
void HandlePrimaryActionClicked();
|
||||
@@ -106,6 +116,15 @@ private:
|
||||
UFUNCTION()
|
||||
void HandleSaveAndQuitClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleSaveGameClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleSettingsClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleQuitWithoutSavingClicked();
|
||||
|
||||
UFUNCTION()
|
||||
void HandleMaleCharacterClicked();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user