Planning Screen & Metadata

Export mission metadata for campaign generation and wire up the Planning Screen: layers, markers, cameras and planning meshes.

Level Layout: Metadata

RP’s campaign generation system needs access to metadata about the level to know what it supports. This metadata is saved in an external data asset, so we do not have to load the level to find it.

  1. In the folder your level is contained within, go to Miscellaneous in the right-click context menu, and create a Data Asset. In the menu that pops up, select the TangoMissionProperties class.
  2. After creating the asset, navigate to it and edit it. Fill in all the properties manually except LevelLayouts. We will pull that data from your created level instead.
  3. Load up your level and select its BP_RandomizationManager.
  4. Find the MissionPropertiesAsset variable within the Randomization Manager, and point it at the Data Asset you just created and filled in.
  5. Run the Randomization Manager’s SaveLevelLayoutData() function. This function iterates every Level Layout Actor in the level, gathers each of their metadata, and exports it to this asset.
  6. Save all (the asset will not save automatically).
Create a Data Asset and select the TangoMissionProperties class.
Fill in all the properties manually except LevelLayouts.
Point MissionPropertiesAsset at your Data Asset, then run SaveLevelLayoutData().

Planning Screen Overview

The Planning Screen is complex and a bit cumbersome to work with, so apologies in advance! It has four central pillars:

  • BP_PlanningPhaseManager
  • TangoMarkerComponent
  • BP_PlanningCamera
  • BP_PlanningMesh

Handling appropriate setup in the Planning Phase Manager and across the level should make configuring the planning screen for individual Level Layouts much easier!

Planning Phase Manager

This Manager contains the definitions for each “Planning Layer”, which corresponds to a Layer of the level you can click on the Planning Screen. Your average level in Rogue Point will usually have 2 or 3 layers.

To set up a Planning Layer, set the LayerCount to the desired number of layers inside the BP_PlanningPhaseManager. It will automatically hide/unhide a corresponding PlanningLayerComponent within itself.

The Planning Layer has a position within the level, as well as a label, and some associated tags for its Floors and Ceilings. There is a helper grid to show you the “perspective” of the Planning Layer as you are positioning it. Imagine the grid as representing the player’s “view” at the Planning Screen.

For each Planning Layer, position it appropriately so it pretty much corresponds with the height of the ceiling for that level — e.g. one grid representing the ceiling of the ground floor, and another the ceiling of the upper floor.

Position each Planning Layer so its grid corresponds with the ceiling height of that floor.

Marker Component

The Marker Component is a reusable component that can be added to any Actor and stores properties used to show Markers to players for that Actor. Developers can configure it with colors, icons, and a bunch of complex rules for how it behaves and shows up.

Critically, the Marker Component carries baked static data for where to show the Marker on the Planning Screen, if it is shown to players, which can vary from Level Layout to Level Layout.

When you run the SetAllLayerActors()editor function on the Planning Phase Manager, it iterates every single Marker Component in the world. Then it calculates a 0–1 position for each Marker Component against each Planning Camera — working out which floor an Actor is sitting on, which ceiling is the “top” level for it, which Planning Cameras it is visible from, and its position on that planning screen.

Sometimes the system setup from SetAllLayerActors()is imperfect, or fiddly. It is sometimes easier to just manually specify the levels for a Marker. In that case, you can go into an Actor’s Marker Component, tick bManualLayers and specify the Floor Name / Ceiling Name manually yourself. We do this all the time in RP.

Example Marker Component properties calculated by SetAllLayerActors() — which floor the actor sits on, which Planning Camera it is visible from, and its 0–1 position on that planning screen.
The Map Check tells you when a Marker Component was not configured correctly.

Planning Camera

BP_PlanningCamerais used to describe a player’s view on the Planning Screen. It is a very basic actor. You simply place it at the right spot in the world and set its OrthoWidth.

The OrthoWidthdefines the extent of the player’s view when they are looking through this Planning Camera. There is a helper grid, visible when selected, to help you visualize this. It must be square (unfortunately).

Place the Planning Camera in the world and set its OrthoWidth.
The grid represents the view players will have when looking through this Planning Camera, per Planning Layer.

A Level can have as many Planning Cameras as it needs. You could use the same one for every Level Layout if you wanted, or have custom ones for different Level Layouts. On RP by default, we typically have a few per level. Level Layouts share these where it makes sense, but we always try to keep them as small as possible (so the player sees as much information as possible at the largest size they can).

A Level Layout has a PlanningCamera property, which you set. Point it at the Camera you want it to use.

Planning Mesh

BP_PlanningMeshis used to draw room shapes on the Planning Screen. It is a 2D “floor” mesh proxy that you place in the world. When the Planning Screen hears that it has to draw a Planning Mesh, it harvests the vertices of that mesh and draws them in 2D on the Planning Screen.

This complexity of having to create these meshes is annoying, but it simplifies lots of other problems that would arise otherwise. On RP, we typically populated out the Planning Meshes right near the end of the development of a level, so we wouldn’t need to keep changing Level Geometry AND the Planning Meshes.

You can associate a Planning Mesh with an Area Manager. If you do so, the Planning Screen for that level will automatically attempt to draw it if that Area Manager was chosen for any Pass Type. Alternatively, you can manually set the Planning Meshes / Planning Areas used by a Level Layout by editing its PlanningAreas and PlanningMeshes variables.

A Planning Mesh can be “real” or not. You can control this by setting bRealMesh. If bRealMesh is true, the Mesh is shown in-game and behaves like a regular static mesh, except it also gets drawn on the Planning Screen. In this way the floor mesh could be used for both purposes at once.

However, on RP we typically do not use “real” Planning Meshes. This is because we usually have quite complex floor geometry, to enable different textures, vert painting, or extra floor details. This extra mesh complexity causes issues when drawn on the Planning Screen, so we typically have a proper floor mesh that is just a standard static mesh, and then a very simplified Planning Mesh that represents the same floor — effectively just a very simplified floor plan of the level.

This is how modSample looks if you show just the Planning Meshes, set to bRealMesh so you can see them — effectively a very simplified floor plan of the level.

The Planning Screen attempts to draw an outline around any rendered Planning Meshes too, for style. However, if the geometry is quite complex, this might not work or might look bad. In 80% of cases in stock RP, the automatic generation is sufficient.

When the automatic generation is not sufficient, you can add a SplineComponent to the Planning Mesh, and draw the line yourself using the spline points. When the Planning Screen calls the Planning Mesh, it checks whether it has any attached Spline Components. If it does, it sends their spline point data instead of its own vertex data. It does this for however many Spline Components it has, so you can have as many lines as you want per mesh!

The Planning Screen bringing it all together: a Level Layout viewed through a Planning Camera, rendering a set of Planning Meshes across two Planning Layers (Lower and Upper).