Menus, pause and saving¶
The menu is New Game, Continue, Load and Quit, and the pause menu adds Resume and Save.
The screens¶
| Widget | What it is |
|---|---|
BP_MainMenuWidget |
Title, subtitle, version, and the entry list down the left |
BP_PauseMenuWidget |
The same layout without the subtitle, over a dimmed backdrop |
BP_MenuEntryWidget |
One line, 384 x 56 |
BP_SlotPickerWidget |
The slot list, used for new, load and save |
BP_SaveSlotWidget |
One slot row, with its thumbnail |
A menu is a complete Widget Blueprint, not a page built from data. To add an entry, drag a BP_MenuEntryWidget into the Designer, fill in its Id and Label, and add a branch for that Id in the controller.
Warning
An entry's identity is its Id, a Name, not its label. An entry with an empty Id does nothing when clicked, silently. It is the first thing to check when a menu button feels dead.
The slot picker¶
One widget serves three jobs, chosen by Mode:
| Mode | What clicking a slot does |
|---|---|
NewGame |
Wipes that slot and starts a fresh game |
LoadGame |
Loads it |
SaveGame |
Saves over it |
SlotCount is five, on the game instance. A row shows the thumbnail, SLOT N, the day and balance, and when it was written. An empty slot says EMPTY, and the one you are playing says CURRENT.
Continue loads the most recently written slot, and hides itself when there is none.
What is saved¶
- Money, the journal, the rating, the day, the hour.
- Shelf contents, row by row.
- Placed structures, matched back by their
DA_and transform. - Boxes and what is in them.
- The roster and its shifts.
- Pending orders, market quotes, running campaigns, granted unlocks.
- Customers, because their baskets hold stock that has already left your shelves.
Not saved: any AI's current target or task, employee positions (the roster puts them back), your own position (you return to the PlayerStart), and a sale in progress, which is cancelled with its goods returned.
Adding your own state to the save¶
Every manager implements two functions, and the game instance calls them:
| Function | What to do with it |
|---|---|
CollectInto(Save) |
Write your own state into the payload |
RestoreFromSave() |
Read your own state back. Call it last in your BeginPlay |
Add your fields to SG_StoreSave, then fill them in those two functions. Nothing else needs to change: the world always starts as a new game and the save overwrites it afterwards, so there is no start-up order to respect.
SG_SlotHeader is the second, tiny object per slot - day, balance, rating, timestamp - and it is all the menu reads to draw a row.
The thumbnail¶
It is a real .png written next to the save, captured from your point of view at save time and loaded back when the menu draws the row.
Deleting a slot leaves its .png behind, harmlessly: it is only loaded when a header exists, and the next save to that slot overwrites it.
Pause¶
Pause lives in BP_StorePlayerController, and it refuses while the closing modal or the daily report is up.
If you extend it, remember that world timers do not run while the game is paused. Anything a paused screen depends on has to be driven from a widget Tick, which does run.
The menu map¶
L_MainMenu is a copy of the street with the gameplay taken out and a slowly drifting camera. Two things to watch if you build your own:
- A child of
CameraActorconstrains the aspect ratio by default, which puts black bars either side of the menu. Turn it off on the class defaults and on the placed instance. UI Onlyinput mode survivesOpenLevel, so the gameplay controller has to re-assertGame OnlyatBeginPlayor you spawn in the shop unable to move.
Sounds¶
Every button plays the same two sounds, and they live in the button style, not in a graph:
| Sound | Where |
|---|---|
SC_UIHover |
Style -> Hovered Sound |
SC_UIClick |
Style -> Pressed Sound |
Those are the only two slots Slate actually plays. Keep replacements short and low: a high tonal beep reads as science fiction, which is not what a shop sounds like.