Skip to content

Commit

Permalink
Merge branch 'release/1.4' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
muit committed Dec 9, 2020
2 parents 53db555 + cda9b82 commit c40f37a
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 69 deletions.
7 changes: 2 additions & 5 deletions Docs/_sidebar.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
- [Introduction](/?id=save-extension)

- Quick Start
- [Installation](quick-start/installation.md)
- [First Steps](quick-start/first-steps.md)
- [Presets](quick-start/presets.md)
- [Filters](quick-start/filters.md)
- [Slots](quick-start/slots.md)
- Resources
- [Actor Settings](resources/actor-settings.md)
- [Slots](resources/slots.md)
- [Multithreading](resources/multithreading.md)
- [Configuration](resources/configuration.md)
- [Level Streaming](resources/level-streaming.md)
- [Lifetime Components](resources/lifetime-components.md)
- [Saving Process](resources/saving-process.md)
- [Loading Process](resources/loading-process.md)

- [Credits](credits.md)
1 change: 0 additions & 1 deletion Docs/quick-start/filters.md

This file was deleted.

Binary file added Docs/quick-start/img/filter_class_allowed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/quick-start/img/filter_class_rejected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/quick-start/img/preset-details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 24 additions & 4 deletions Docs/quick-start/presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ Then we assign our preset class we want to use in **Preset**.

#### In Blueprints

The preset can also be changed from blueprints in runtime calling:
The preset can also be changed from blueprints in runtime by calling:

![Set Active Preset](img/set-preset-bp.png)

## Settings

![INSERT DETAILS SCREENSHOT HERE]()
![Preset Details](img/preset-details.png)

?> All settings have defined tooltips describing what they are used for. Check them moving your mouse over the property.
?> All settings have **tooltips** describing what they are used for. Check them by moving your mouse over the property.

A brief overview of the settings available:

* **Gameplay**: Configures the runtime behavior of the plugin. Debug settings are also inside Gameplay. [Check Saving & Loading](saving&loading.md)
* **Serialization**: Toggle what to save from the world.
Expand All @@ -41,4 +43,22 @@ The preset can also be changed from blueprints in runtime calling:

## Filters

TODO
Filters allow us to select which classes will be saved and which classes won't.
This applies to actors and components and can be edited from the Preset.

### Allowing classes

If a class is added to a filter, that class and all its children will be allowed, meaning they will be considered for saving, their properties will be saved, etc.

![Class allowed](img/filter_class_allowed.png)

*In the image: We allow Character, so all children character classes will be saved.*

### Rejected classes

We can also reject classes from a filter, meaning they wont be considered for saving.
?> Only children classes of allowed classes will be allowed to be rejected.

![Rejected class](img/filter_class_rejected.png)

*In the image: We reject TutorialCharacter from the previous image, essentially saving all characters except TutorialCharacters.*
15 changes: 15 additions & 0 deletions Docs/resources/actor-settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Actor Settings

---

Each actor blueprint can have its own configuration which is edited directly inside the blueprint:
![Open actor settings](./img/actor_settings.png ':size=450')

This settings get translated into actor tags so they can also be added in C++.

- **Tags**: Should save actor tags?
- **Transform**: Should save position, rotation and scale of this actor?
- **Physics**: Should physics be saved? **Transform** is required to be enabled to save physics.

!> If you can't see *"Save Settings"* window opened it can be manually opened from **Window -> Save Settings**<br>
![Open actor settings](./img/open_actor_settings.png ':size=300')
45 changes: 0 additions & 45 deletions Docs/resources/configuration.md

This file was deleted.

Binary file modified Docs/resources/img/actor_settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Docs/resources/img/save_settings_zoom.png
Binary file not shown.
11 changes: 6 additions & 5 deletions Docs/quick-start/slots.md → Docs/resources/slots.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
# Slots

In Save Extension, we refer to "slots" as an **instance of a saved game** and they are identified by a number.
Most of the times we will think of slots as the actual saved files.
In Save Extension, we refer to "slots" as an **instance of a saved game**. They can either be identified by a name or a number.

## Slots as files

An slot is composed of two individual files. One is the slot info, and the other the slot data.
Slots are saved into a single file named after the slot name.

To avoid having to load all save files entirely when, for example, displaying a list of slots in a menu, data is stored in two sections:

### Slot Info

Contains **lightweight** information about the saved game. Information we want to obtain without needing to load the rest of the slot.
Some examples are player level, xp, progress, player name, zone or area, current objective or thumbnail.

The game can access all slot infos very quickly without requiring to load game, which is very useful for UI when we want to display a list of all saved games.
The game can access all slot infos very quickly without requiring to load the rest of the data.

### Slot Data

It is here were all heavy data is contained!
The bulk of any saved game.
All information serialized from actors and components is stored in the Slot Data, as well as any other data the game may need.

All levels, players, AIs and game systems configured to be saved are contained here.
Expand Down
23 changes: 16 additions & 7 deletions Source/SaveExtension/Private/Serialization/SlotDataTask_Saver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,12 @@ void USlotDataTask_Saver::SerializeWorld()
const UWorld* World = GetWorld();
SELog(Preset, "World '" + World->GetName() + "'", FColor::Green, false, 1);

BakeAllFilters();

const TArray<ULevelStreaming*>& Levels = World->GetStreamingLevels();
PrepareAllLevels(Levels);

// Threads available + 1 (Synchronous Thread)
const int32 NumberOfThreads = FMath::Max(1, FPlatformMisc::NumberOfWorkerThreadsToSpawn() + 1);
const int32 TasksPerLevel = FMath::Max(1, FMath::RoundToInt(float(NumberOfThreads) / (Levels.Num() + 1)));

Tasks.Reserve(NumberOfThreads);

SerializeLevelSync(World->GetCurrentLevel(), TasksPerLevel);
Expand All @@ -194,6 +192,20 @@ void USlotDataTask_Saver::SerializeWorld()
RunScheduledTasks();
}

void USlotDataTask_Saver::PrepareAllLevels(const TArray<ULevelStreaming*>& Levels)
{
BakeAllFilters();

// Create the sub-level records if non existent
for (const ULevelStreaming* Level : Levels)
{
if (Level->IsLevelLoaded())
{
SlotData->SubLevels.AddUnique({ *Level });
}
}
}

void USlotDataTask_Saver::SerializeLevelSync(const ULevel* Level, int32 AssignedTasks, const ULevelStreaming* StreamingLevel)
{
TRACE_CPUPROFILER_EVENT_SCOPE(USlotDataTask_Saver::SerializeLevelSync);
Expand All @@ -207,14 +219,11 @@ void USlotDataTask_Saver::SerializeLevelSync(const ULevel* Level, int32 Assigned
const FName LevelName = StreamingLevel ? StreamingLevel->GetWorldAssetPackageFName() : FPersistentLevelRecord::PersistentName;
SELog(Preset, "Level '" + LevelName.ToString() + "'", FColor::Green, false, 1);


// Find level record. By default, main level
FLevelRecord* LevelRecord = &SlotData->MainLevel;
if (StreamingLevel)
{
// Find or create the sub-level
const int32 Index = SlotData->SubLevels.AddUnique({ *StreamingLevel });
LevelRecord = &SlotData->SubLevels[Index];
LevelRecord = FindLevelRecord(StreamingLevel);
}
check(LevelRecord);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,13 @@ class USlotDataTask_Saver : public USlotDataTask
protected:

/** BEGIN Serialization */
void SerializeLevelSync(const ULevel* Level, int32 AssignedThreads, const ULevelStreaming* StreamingLevel = nullptr);

/** Serializes all world actors. */
void SerializeWorld();

void PrepareAllLevels(const TArray<ULevelStreaming*>& Levels);

void SerializeLevelSync(const ULevel* Level, int32 AssignedThreads, const ULevelStreaming* StreamingLevel = nullptr);

/** END Serialization */

void RunScheduledTasks();
Expand Down

0 comments on commit c40f37a

Please sign in to comment.