You are on page 1of 60

PROJECT MIGRATION:

1) Go to your Target project (HOST) and, under project settings, search OBJECT
2) Add two new object channels, default response: IGNORE
3) Migrate The Project to the HOST project

If you don’t want to use the WATER Plugin from Epic Games go to EDIT > PLUGINS > search for “water” and
disable the water plugin. Restart the editor then migrate.

If you want to use it in your target project be sure to enable it before migrating.

In the project the plugin is only used for the water shader for the ocean, so you can choose to disable it and
to use another water shader.

IMPORTANT: You will find some updates that were made for the version 1.5/1.6 that are in blueThese are
important updates and we suggest you to read them.
Disable enable WATER plugin

Create the 2 custom Object channels with default response = ignore


PRESENTATION:
This project is a 100% blueprint combination of two systems: Physic based movement and spline based
movement that Is used to move floating vehicles both manually and automatically without the need to use
a navigation mesh.

1) Use a Master blueprint to create several combinations of hull / propulsion systems and customize
your ships adding decks, bollards, cranes, radar systems and any object directly in the viewport of
the child blueprint of your new ship.
2) If you want to make changes you can edit the master blueprint and all the ships you have created
will be affected by the modifies without the need to edit every blueprint.
3) We have provided 10 example ships, with different size and propulsion type to show the
possibilities of the ship master blueprints. You can create a small outboard motor boat or a very
large ship with any combination of propellers / rudders and also with different floating mechanics
(hovercraft or submarines).
4) Each ship can carry a lot of static meshes, instanced static meshes, skeletal meshes etc. You can
add a custom logic inside any child blueprint according to the type of ship. (for example a dynamic
cargo system that can change from containers to gas tanks or oil tanks, opening doors for a ferry,
full interiors that can be explored with a character, lights, control systems etc).
5) The movement of the ship can be: manual using physics (we made a blueprint float system inside
the ship master), automatic using physics (go to a point), automatic using splines (follow a route).
6) Ships can switch from physic based movement to spline based movement during game to be able
to reach any point of a level using premade routes.
7) We made a double avoidance system: one is for physic based moving AI ships and one is for spline
based moving AI ships so they won’t collide and you can have a lot of ships moving in a crowded
space
8) We’ve added two important systems: a radar (that is a minimap) and a real sonar or depth finder
that will find the real sea depth in meters and will draw a graph
9) There’s a fully working classic ship control system, with levers, helm (the steering wheel) and
compass system, everything is animated and it’s reusable in other ships because it’s made as a
separate actor
10) Ships can collide with each other when they are physic objects and a physic moving ship can collide
with a spline moving ship.
11) Ship can have interiors, we’ve added an automatic door system that is reusable, the door, the angle
of opening etc can be changed and it’s based on the event hit with a pawn. With proper collision
setup a ship can be explored by a character
12) Everything is based on timers, no event tick is used on the ships. We’ve made 3 custom timers, high
frequency, average frequency and low frequency to handle different functions according to the
frequency they have to be updated to minimize performance costs.
13) There’s a route blueprint that is using a spline to draw routes that are used as “roads” that can
connect several points in the level. These routes don’t need to be linked together because ships can
move from one route to another using the physic based movement system.
14) The AI System is a blueprint system that don’t use AI controllers or navigation meshes. We’ve
created a system to easily program and expand the AI system that is using “steps” that are added
to an array and that the ship will follow starting from the first to the last.
15) You can also create premade programs using a data table where you insert the various steps and a
unique enumerator name to quickly recall a program also during game.
16) We have also added an animated port crane (post panamax container crane) that can be used to
move containers from a ship or on a ship.
17) Finally there’s the port blueprint that is a block system using 2k units squared blocks and a master
blueprint. You can create several child blueprints and then create the port from the viewport of the
blueprint adding blocks. Then the port can be used in several maps, moved or modified.

The project is designed to be a starting point for users that want to have moving ships in a game and
it’s easy to expand with additional functions and to use.

DISCLAIMER:
The model of the Titanic ship has been made to reproduce a 3 propellers and 1 rudder ship, using a real
world model design inspired by the 19th century ships. But the model is not intended to be crashed or to
sink and we respect the people who lost their life in the real Titanic ship. The 3D model used it’s just a
reproduction and it’s not intended to simulate the real ship. Any other ship in the project it’s made basing
on our imagination and it’s not linked or related to any existing ship.

3D MODELS:

The 3d models we have included in the project are intended to be changed with your own 3d models. But
they are also made to be used in a game, it really depends on your target project. The idea is to provide you
the basics to work on and our goal is to make sure that these basics you will work on will be reliable and
reusable with any models and with additional parts.

So, if you plan to make, for example, an ekranoplan you can reuse the logics we provided for constraint
based meshes, for movement, collisions, AI etc and add your own logic to the Master blueprint.

Waves:

We didn’t implement waves at this point but you can use the Epic Water Plugin to replace the floating
system that is in the project and keep the propulsion system. Waves will require more resources and the
project is intended to be used also on low end computers. Also we have to disable the floating physic
system during the game to make the ship go along a spline and so we did our floating system without
waves.

Wind:

Wind is something we would like to add but we leave it for a second stage of the development of the
project. Anyway we have made some tests and we can give you some informations to implement it right
now in the current project. (just mail us to info@zerstorengames.com)
UPDATE 1.6: Carry Physic actors / Vehicles on a ship. See the video
https://youtu.be/K1lAp-Gjmew

We’ve added a function to the Master ship blueprint to allow, if enabled using the “CanCarryPhysicActors?”
Boolean value to true, the ship will look for physic actors collisions and will automatically create a constraint
to avoid the physic actors to move when the ship is moving. This is important because otherwise

The movement of the ship won’t be “transmitted” to the physic actors that are over the ship.

So, there’s a new function :


That is F_CarryPhysicActors over a Ferry. This function will check for any physic actor with a collision object
channel “Physic Body” set to block, with a root component that is a static mesh and that is also simulating
physics. This is a common setup for a physic actor, the root component is a static mesh that is set to
simulate physics. The constraint will be created when the ship moves along a spline. If you plan to carry
vehicles also when the ship is moving using physics you can change the second branch condition, adding the
stances that you are interested in, for example GOTOPoint etc.

SHIP VEHICLE COLLISIONS:

Another important thing is the collision of the wheels with the ship. The ship are set to a custom collision
channel that is VEHICLE object. But they are also set to ignore vehicles collision to avoid collisions between
two components of the same blueprint. The hull instead is set to block the vehicle collision. In the Tank
example the wheels of the tank and the body where set to ignore the vehicle collision and if you set them to
block this channel the tank will mess up. So, there are 2 solutions:

1) Change the vehicle collision to PhysicActor, for the wheels, suspensions etc, that won’t need a
collision with other tanks you can set the collision to Physic actors and ignore physic actors, block
vehicles

2) Change the ship collisions, in the blueprint of the ship you want to use as ferry, to block the vehicle
wheels and body collision channels.. Consider that the important is not to change the hull collision but
the collision of the part the vehicle will drive on. So, in the ferry example, it’s a static mesh attached to
the hull and this is the collision to change to allow a vehicle to drive over the ship. Also ramps should be
set to block the type of collision of the wheels and of the body of the vehicle
After this is done you should be able to drive the vehicle on the ship. The problem can be that the vehicle
can’t move when the ship is moving because it’s tied with a constraint and it would be better to stop the
move forward input. You can do this using a cast to actor to be added in the function and use a Boolean, on
the vehicle to avoid using inputs when the vehicle is attached to the ship.

V1.7: USING VEHICLE MOVEMENT COMPONENT BASED VEHICLES OVER THE FERRY or Other Ships: Video:
https://www.youtube.com/watch?v=fOxXr0QwFkg
We’ve added the possibility to carry a vehicle with the default vehicle movement component from epic on a
ship: Just be sure that the skeletal mesh has a vehicle or physic body collision object channel set to block and
that the ship Is set to “cancarryphysicactors”

Use the “Debug_CaryVehiclesTrace” to understand the area that will be checked to carry vehicles, adjust the
“carryVehiclesRadiusMultiplier” to increase the size of the area to check (only on Y side, X side is
automatically calculated and won’t need adjustments).

In the BP_Shipmaster check the function F_Check for Moving actors to see how the system works. You can
add a different logic to the blueprint according to what you need to carry and when.

V1.6: USING EPIC BUOYANCY SYSTEM: watch video:


https://www.youtube.com/watch?v=6uQ9D4hpKak&feature=youtu.be
It’s really simple to implement the Epic buoyancy system to this project. First of all be sure to have the
Water plugin and the Landmass plugin enabled.

Then create a level and the landscape. Before clicking create be sure to set the “enable edit layer” Boolean
to true. Assign a material to the landscape (the project MI_WTS_Landscape is made to have an height layer
to create beaches) and make a flat landscape to be sure that this will work.

After that you can go in the Select Mode (the third icon after SAVE CURRENT, the one with the mountain)

Type water in the search on the left and select “WATER BODY OCEAN”

If you did everything correctly changing the Z location of the Water Body Ocean should change the shape of
the island.
Then check, under WATER BODY OCEAN The collision extend

Set it to something like 150000,0 X and 150000,0 Y and it should cover the whole map.

Just edit the Blueprint BP_Ship_Master and search for “Float”, you will find the F_Float that is the function
we use in the project

To make ship floating. Unhook the F_Float function or add a branch to disable it.

You can add a buoyancy component to the master blueprint or to the child blueprint. If you use a Boolean
instead than unhooking the function you can also add the buoyancy component to each child blueprint you

Want to use with epic buoyancy.


At this point drop a ship in the level, a bit higher than the ocean level and add pontoons to the buoyancy
component. If you use the Titanic ship this is the setup:
Also add some angular damping to the shipbody:

At this point, drop a BP_Interface in the level and press Play. You should be able to drive the ship.

If you want to change the waves be sure to copy, from the editor content directory/water plugin the
following materials and the gerstner waves file:

The gerstner waves file is used to create the waves, be sure to select the waterbodyocean and change the
gerstener waves file to the one you’ve copied:
This is how we set the waves for the video but it’s just a suggestion:

At this point you should be able to drive the Titanic and to also have the Epic buoyancy system.

IMPORTANT: If you promote to variable something be sure to do it in a map without any child actor of the
ship opened otherwise, if you promote to variable a value like 15, on the other child blueprints you will have
a value of 0 and you will need to check every child blueprint to set the variable to the value desired. So, if
you make modifies, go in the Map_Entry where there’s nothing and be sure to close every child blueprint in
the editor.
FREQUENTLY ASKED QUESTIONS:
1) Can I use the water plugin for buoyancy? The water plugin can be used for buoyancy by removing
the “F_Float” function inside the ship blueprint and maintaining the function used to move the ship
using forces. However it’s not clear if the buoyancy can be disabled during game like the blueprint
buoyancy is.
2) Can I make ships move without the need of an interface? Yes you can remove the BP_Interface
from the level and let the ship move using custom programs and set them to repeat the cycle
3) Can I make this multiplayer? Both spline based movement and physic based movement can be used
in multiplayer but there’s not replication at the moment and it’s untested in multiplayer.
4) Can I make a sail ship? The project is made to be used with engines, we have no wind blueprint in
the game and controls are intended to be used with a simulated engine.
5) Can I make an alt-azipod propulsion system? Propellers and rudders can be connected like in the
outboard motor boat and they have an angle that can be covered that is about 40° using
constraints. It’s possible to set the constraint to free or to a bigger angle and to make the propellers
rotate by 180° to simulate alt-azipod ships.
6) How easy is to create a new ship? The main difficulty is to create the 3d model to be used by the
ship system in a 3D modeling software. We generally split the ship in parts: The hull, the rudders or
the rudders, the propellers. These are the parts that must be exported as stand-alone parts
because the hull is the body that simulate physics and must have a simple collision. Rudders and
propellers are using constraints so the pivot point must be the point of rotation. Everything else
can be also split to design the collisions and to optimize the performances. For example if the ship
is large and there are a lot of lifeboats it’s better to export a single lifeboat with or without the
mechanism to drop them from the ship and then use a Hierarchically instanced static mesh
component to create instances of the lifeboats that will be attached to the ship. So, the 90% of the
time will be in the 3d modeling software. Once every part is made and the child blueprint is created
it’s very easy to replace and move parts, constraints etc. Then you have to test the ship in the water
and play with parameters we have added to customize the ship (propulsion force, stabilization,
steering torque etc).
7) Can the system be used with world composition? It’s not tested but generally the water plane is not
repeated in each level so you can create an ocean level and drop the ships and the routes in this
level so they can move across the whole map.
8) Can the ship sink? Yes, it’s possible to implement a sink function that will gradually reduce the
floating force to make the ship sink. You can also reduce the stabilization force to make the ship roll
over or pitch.
9) How many ship can I use simultaneously? There’s no limit to the amount of ship you can use but
there are a few things to consider: 1) don’t make all the ships move at the same time, we’ve added
docking points to make the ships stop for a time interval, we’ve added a delay before the ship
starts and several ways to make them not move simultaneously. When the ship is not moving
physics will disable and also a lot of functions are not working to make room for other ship to move
freeing some CPU usage. So you can add a lot of ship to the scene (bigger ships with a lot of
components are heavier, smaller ship are more light to render and to move) but try to make them
move in different time frames
10) Is it possible to cause damages to the ship after hitting something? It’s possible flag as hidden in
game the hull and replace it with no-collision parts of the hull with damages. This is not
implemented because it will require more static meshes and project size will grow too much.
11) The ship is turning around a point and it takes a lot to reach the location and rotation. This is
caused by a lack of turn force or a too high propulsion force. The ship will aim, when used by AI, to
a point in a 2D space but if the propulsion forces are not well balanced the ship could have
problems to reach the destination when using physics. Try to adjust the additional steering torque
and reduce the propulsion force multiplier
12) The ship is not taking a route. This can be caused by a too high speed of the ship because the traces
that are made to find a new route are based on a low frequency timer. With a speed below 150
knots, if routes are not placed too close one to each other, the ship should be able to detect the
route required and to reach the point to start moving along the route (spline) without issues. Take
a look at the demo map to see how to place routes in the level.
13) It’s possible to see water inside the ship when accelerating. This is due to the low height of the hull
and to the low pitch stabilization force. A flat ship, with a low Z height can suffer of this problem,
even with a flat sea surface. Try to add more pitch and roll stabilization or to increase the sea level
height of the hull to solve

Project contents: BLUEPRINTS:


1) BP_ShipMaster: (parent class: PAWN) The master blueprint that contains all the logics for the ships
movement and that allows to create a child blueprint class to create as many ships you want.
2) BP_ShipRoutes: (parent class: ACTOR) This blueprint is used for spline based movement by every
ship.
3) BP_Harbour: (parent class: ACTOR) It’s the master blueprint to create a port, You can create a child
blueprint class from this actor and design your own port that will be reusable in any map. The
blueprint uses 1000x1000x1000 units blocks that are instanced (hierarchically instanced static
mesh components). You can add blocks using coordinates remove them, change the block type etc.
4) BP_Port_Crane: (parent class: PAWN) It’s a port crane blueprint used to move containers, it works
immediately after being drag and drop over a Port blueprint (if you created the rails in the port
blueprint) and it’s made using physic constraints and spline based movement.
5) BP_Radar: (parent class: ACTOR) It’s the radar actor that can be placed on any boat, it’s already
equipped with the rotating part and the optional pole to substain it. It creates a sort of minimap to
see other ships, landscape etc. It uses a very low res render target.
6) BP_ContainersSpawner: (parent class: ACTOR) It’s a blueprint to create arrays of containers of
different colors (you can, like with all the other blueprints, use your own container static meshes or
use the included ones). Can be used over a ship or everywhere in the map and it’s based on
hierarchically instanced static mesh components to minimize performance drops.
7) BP_Door_Actor (parent class: ACTOR) It’s a customizable door actor (you can change the door static
mesh, the rotation min and max) and it works with any pawn using the hit event. Also this blueprint
can be used to create a child actor class with preset options, like a different door etc. to quickly
reuse it where needed.
8) BP_Harbour_Walkway: (parent class: ACTOR) It’s the wooden walkway with recharge stations,
bollards etc and it’s used by the harbour blueprint to create docking spaces that can be used by
small ships.
9) BP_Interface: It’s a blueprint that can be drag and drop in the level to enable the Hud provided with
the project. Can be simply be removed by the level if you don’t need the hud but you just want ship
moving without any direct control by the player.
10) BP_Bulkward: (parent class: ACTOR) It’s a blueprint used to create a bulkward using hierarchically
instanced static mesh components and can be used where needed.
11) BP_DockingPoint: (parent class: ACTOR) It’s a blueprint used to create docking points for ships, you
can specify the size of the docking point and the location + direction and ships of a compatible size
can be programmed to automatically go to the docking point and stop there.
12) BP_Anchor_Assembly: (parent class: ACTOR) it’s the blueprint used to add a working anchor system
to any ship. The anchor will move using up and down controls, it uses 2 separate anchors and a
winch. The chain is animated using hierarchically instanced static mesh components and instances.
13) BP_CoalCargo: (parent class: ACTOR) It’s a very simple actor that can be used to create a coal
transport ship, you can place it over the ship hull and can be opened or closed.
14) AC_Sonar: (parent class: ACTOR COMPONENT) It’s an actor component that will provide a sonar
(depth finder) that can record the sea depth and create a graph in the Hud using a small render
target.
15) AC_ViewportChecker: (parent class: ACTOR COMPONENT) It’s a system to reduce performance
costs, can be used to get a Boolean variable when the parent actor is in the viewport to reduce
some non essential things. (for example the rotation of propellers can be disabled when the ship
it’s not in the viewport because you won’t see them so it’s not useful to make them rotating).
16) BP_WTS_Waterplane: (parent class: ACTOR) it’s a waterplane actor that can use any material so
you can use your own water shader. If you already have a water plane you can replace it with yours
just by selecting, in the BP_ShipRoutes, the class of your waterplane.
17) BP_Visual_Control_System: (parent class: ACTOR) it’s an old style steering wheel + engine levers +
compass that can be added to any ship as child actor and it’s working using the move forward,
move righ and yaw of the ship that is attached to.

Project Content: Static Meshes:


There are more than 160 static meshes included in the project, the average is about 5k triangles with
maximum of 20k triangles for some hulls. The only high poly static mesh is for the port crane that is
featuring a very complex stairs system and the static mesh reaches 170k triangles, with 6 LODS but it’s
possible to remove it from the crane body, that instead it’s just 7k triangles.

Each static mesh (Except for very low poly meshes, is using automatically LODS). All the static meshes are
created using Autodesk Maya LT. We generally use a max of 6 LODS based on automatic screen size.
Project Content: MATERIALS, TEXTURES, MATERIAL INSTANCES:
The project is based on a master material that can be used to create material instances:

This materials uses 3 textures: Diffuse, Normal and a Roughness+Metallic+AmbientOcclusion combined in 1


texture. The project was born using 4k textures but due to the large number of static meshes and the fact
that each material instance is using 3 textures we decided to use 2048x2048 textures maximum. Anyway
we can supply a 4k version of each texture if you ask us, we have all the templates of substance painter so
we can export textures using 4k resolution. But including them in the project that is 2GB size would have
made it like 5 or 6 GB. So we offer this solution, if you want the 4k version just write to
info@zerstorengames.com and we will give you a link to download them.
Small parts are using 1024 or 512 textures. All the textures are made using Adobe Substance Painter.
IMPORTANT INFORMATIONS:
1) The Project is using the Unreal Engine 4.26 “Water Plugin” just for the water shader. Buoyancy it’s
made in the ship blueprint and it don’t require the plugin. We just enabled it for the very nice water
shader that comes with the plugin. Because it’s an experimental plugin we made the project to be
perfectly working even disabling the plugin. If you disable it the water shader will be a grey material
and you could replace it with another water material. Landmass plugin it’s not enabled and
landscapes that are contained in the project are normal landscapes without the edit layers enabled.
2) The BP_ShipMaster can be used to create any type of ship of any size except for Alt-Azipod systems
that are not included in the project because they would require a dedicated control system.
Anyway it’s possible to modify the blueprint to allow the use of alt azipod systems basing on
outboard motors that are already set up in the RHIB boat.
3) Very large ships, with lots of components are heavier to move, in terms of CPU and GPU usage, and
generally ship 3d models have a lot of polygons so they are not game ready. For this reason we
designed every 3d model in the project using Maya to be as low-poly as possible without losing too
much realism and to work properly in the UE4 engine. However there are a lot of 3d models
available on different websites and, with some modifies, they can be used to create very realistic
ships if you don’t mind to use them in a game but you want to make a video or a simulation etc.
4) In the project the cargo ship and the ferry ship are made to be explored by the third person
character so all the collisions are working to allow the player movement inside the ship, even when
the ship it’s moving. However the character movement component don’t consider the movement
of the ship when, for example, you want to jump. This will cause the character to remain stationary,
as it was on a steady ground but the ship will continue to move and this will produce a sort of jump
back when you want to jump on the place or forward. Also falling it’s a problem when the ship
moves. There’s no solution for this, it’s a common issue of the default character movement and we
didn’t modify the character to work properly on moving ships.
5) When moving using splines physic constraints becomes wobbling so we had to limit the use of
constraints on ships. For the constraints that we couldn’t remove like the ones that moves the
propellers and rudders we have made a system that will disable the physic simulation of the static
meshes when moving along a spline so they won’t move in a strange way when the ship is moved
along the spline. If you plan to add constraints to the ship be aware that they will become very
glitchy. For these reason the lifeboats of the cargo ship, that were initially made using constraints
and were working perfectly when the ship was moving using physics were replaced by a non physic
simulating system to be deployed.
6) Physic based vehicles relies on the FPS. If your game has low FPS physics will become slow and the
floating system can have problems to keep the sea level and stabilization. We’ve added a system
that will detect the FPS and will stop the physic simulation if the FPS are dropping suddenly for
some reason to avoid glitches but if you have a constantly low FPS (like less than 25 fps) we don’t
recommend using physics. For this reason we also added spline based movement that instead it’s
much more reliable in a low FPS situation. But the system is designed to work with more than 30
fps to work properly.
7) When importing 3d models it’s very important to consider the pivot points of the models both for
physic based movement and for spline based movement. The pivot point of the hull is the pivot
point of the ship so rotations along the spline and forces won’t be realistic if the pivot point of the
hull is not centered in the center of mass of the ship.

SHIP BLUEPRINTS INCLUDED IN THE PROJECT:


To make sure that users will have a reference to create different type of ships we include several ships to
the project.

1) TITANIC: It’s a 266 x 28 meters reproduction of the Titanic. IT uses 3 propellers and one rudder

2) Cargo: It’s a 143 meters long, 18 meters wide ship with two propellers and two rudders. It’s the
base of the BP_ShipMaster blueprint because it’s a very traditional propulsion system and can be
used on every ship of any size. The whole propeller, rudders and shaft assembly it’s resizable so you
can use it also on small ships. The cargo ship has interiors, doors, stairs etc. The hull colors (3) can
be changed using a different diffuse textures, it has 2 retractable lifeboats that can be lowered
(they can’t be used but they can be replaced with a BP_ship child actor of the same lifeboat when
on the water just by hiding the ship lifeboat and spawning a BP_lifeboat. The cargo ship also
features an enum to change the cargo type, can be used to carry containers, coal, liquid gas, Oil or
nothing and you can easily add any type of cargo using the same function.
3) Ferry: It’s a 66 meters long, 10 meters wide ship that can carry people, vehicles etc. It’s equipped
with 2 openable doors that will automatically open when nearby a harbour ramp. The ship can use
ferry routes to create an automatic transport system.
4) PILOT: it’s an 18 meters long, 6 meters wide ship that can reach high speed. It’s also used for a
military version of the same ship

5) RHIB: It’s a 13 meters long, 4 meters wide boat like the coast guard RHIB boats it uses 2 propellers
6) RHIB 2: it’s a smaller version of the other RHIB but this one uses two outboard motors to show how
to setup this type of propulsion system to any ship using the BP_ShipMaster blueprint as starting
point.
7) Hovercraft: It’s a 50 meters long, 40 meters wide Hovercraft ship, made using the BP_ShipMaster
blueprint and it uses two aircraft engines and propellers to move. It can also move on the
landscape. (you can also add other surface to make it move on but we limited the movement to
landscape only, as default, to avoid moving over other objects that are not made to be run over by
an hovercraft.

8) SUBMARINE: It’s a 146 meters long, 16 meters wide submarine that can go underwater. It uses a
single propulsor with 2 rudders mounted vertically. It’s made using the same BP_ShipMaster but
there’s a Boolean variable that allows the ship to move underwater using Z and X keys on the
keyboard. Like for the hovercraft, the project it’s not made for hovercraft or submarines so there
are limits, for example the submarine will be affected by the post process of the waterplane and it
don’t have interiors. Also it can’t pitch down like real submarines, it will remain horizontal. (it’s
possible to edit the float function of the BP_ShipMaster to also allow the submarine to pitch down
or up with some modifies that we can help you with, if you want)
9) FastBoat: it’s a 19 meters long and 4 meters wide very fast boat, designed to reach high speed to
show how quick a ship can be using physics. It’s designed to reach 150 knots (converted from UE4
units) as max speed but we tested it to 300 knots or even more and it performs well.

10) Lifeboat: It’s a small ship 7 meters long, 2 meters wide, that can be used as lifeboat for the cargo
ship
PORT CRANE BLUEPRINT:

The blueprint let you drive a huge port crane that will move using a spline that is made by a rail of the
BP_harbour, you can simply drag and drop it in the scene. The crane also uses constraints to move the
trolley and the cargo hook system. The movement is very easy and it can take containers from the
BP_Container Spawner blueprint

The crane also have a control cabin and a stair system to go up to the top of the crane.
BP HARBOUR:

The harbour blueprint is designed to have reusable harbours just by creating child blueprints of the master
one.
We included a child blueprint of a standard port that is made using about 270 blocks. Blocks are
hierarchically instanced static mesh instances. You can add a USER SET BLOCK and specify the settings, like
coordinates, block type and other things like bollards, dampers, walls, light poles.
You can add any type of object to the block structure, for example, if you want to add a fire hydrant you
can edit the structure of the harbour block:

And then, inside the blueprint, you can use this Boolean and transform to position it inside the main
placement function:
And you can also add child actors, skeletal meshes and everything else.

We already included many type of blocks:

But you can add an entry in this enumerator above and then, inside the master blueprint you can duplicate
one of the components on the components tab and select the new static mesh, then go to the macro
M_GET_HISMC
And hook the new component to the list.
At this point, when you enter a new “USER SET BLOCK” the new block should be in the list and you can
rotate it and position where needed from the blueprint child viewport.

When you finished creating the port you can simply drag and drop it in every level you want:
SHIP ROUTES:
UPDATE 1.5: We have removed the 4 splines to only use 2. The reason is because there are less components
and because with large ships it’s not useful to have a secondary spline to be used to avoid
The large ship. Instead we added a system to use the right vector for the proper distance so ships will move
Right when another ship is coming on the same route in a contrary direction.

Ship routes are the basic to allow the ships to move along a spline. Ships don’t need that actor in the level
to work, they can work using physics if manually drived or automatically using physics to go to a point
(location) in the level. But if you have a very complex navigation path with several ports, narrow passages
etc it’s better to use a spline based movement:

The blueprint will use the Waterplane actor class to align with the coordinates of the sea level.
If you specified the waterplane class you can just drag and drop in the level and then select the parameters
as you want:
You can give it a name, a Type of Route that is the enumerator name to define the route. If it’s a transit
route then it can be used by any ship to connect different ports, like in the picture above.
Type of routes:

You can add any other type of route in the enumerator. After we will cover the ship programming and how
to make the ship only use this particular route.

In case of a ferry route you will probably need to use MAX SPLINE L Length OFFSET and other offsets to limit
the distance that can be reached by the ferry to match with the ramp.
You can see this example:
In the picture above the ferry pivot is exactly where the light-blue arrow pointing up is. This arrow is
positioned adjusting the offsets for the RIGHT SPLINE. So, Min Spline R length offset is this limit, the start of
the spline is at 9000 units so the ferry can go further. The end of the spline will be different, according on
how you placed the spline, so it’s better to make this test: take the ship and move it manually along the
spline until the position you want, then adjust the proper offset and check the light-blue arrow. When the
light blue arrow is positioned on the pivot of the boat you have the max offset.
Always remember that both splines starts and and end in the same position:

But the right spline (you can use the name BP_ShipRoute4 Ferry START) to understand where is the start of
the route and the other side is the end. So, the right spline of the image above is generally used to go
forward, the left spline is generally used to go backward. Ferries can go forward and backward on the same
spline so they don’t need to invert the direction to go back. But other ships will use the right spline to go
forward and the left one to go back, unless specified in the program they have to follow.
The spline min and max has been introduced because spline points are positioned at a fixed distance, so
you can’t make the spline end exactly where you want just positioning the spline, using the OFFSETS you
can tell the ship exactly where to stop at the end and at the start of both splines. You can also use different
values for the left and right spline. So, if you have two different ferries, one is shorter, one is longer, they
can use the same route, one on the right and one on the left. But the offsets, if properly set, will help them
to approach the ramp without going too forward or to remain too distant.
The ferry will open the ramp as soon as it reaches the port ramp, automatically. This is implemented inside
the ferry child blueprint.

This is an example of a feature that is not in the Master blueprint because it’s not generally used by every
ship, but can be easily implemented inside the child blueprint.

Another very important route is the Harbour route. It allows to enter or exit the harbour and it’s used by all
the ships. It’s important because the harbour corridor can be narrow, there’s the depth of the sea to be
considered and this route will help ships to go out or to go in the harbour without problems.

As you can see the route spline is made by 5 splines, 1 is the green one, used to draw the route, the other
ones at the left and right of the green splines (purple) are the one used for navigation. Then there are two
other purple splines. These are used by ships avoidance system to allow two ships to avoid collision if one
spline is used by a ship. The other ship will use the far right or far left spline.

The Green Arrows are used by ships to find a route. They use a Custom channel that is default IGNORE. So
the trace will only look for this particular object channel, ignoring everything else.
These two custom channels are important to add to your target project if you want to use the spline
navigation system and the docking system.
Under project settings type object:

You will see two object channels, default response: IGNORE. These must be created, in the HOST project
before migrating the Guest project (this one).
So, create them and set the response to IGNORE.
The green Arrows are instances of a Hierarchically instanced static meshes. These instances have just a
collision for the “ShipRouteTrace” object channel. They won’t interfere with other channels you have on
your target project if you set them to DEFAULT > IGNORE.
Tracing to find these arrows is the simplest way, without using elaborate functions to get a distance on the
spline closest to the location of the ship.
So, when a ship is looking for a particular route a progressive trace is performed, if one is found the new
route is taken. A this point the ship will move using physics to the arrow location, once reached the ship will
align with the arrow and proceed with a spline based movement.
With a lot of routes crossing it’s important to minimize the results of the traces to find the routes, so the
function, inside the BP_ShipMaster, is designed to only look for a specific route type and discard the other
found.
Without using this system it would be hard, for a ship placed in this harbour to reach the route above on
the other side of the port barriers:

If the ship finds an arrow that is not possible to reach by sea that arrow is not considered.

BLUEPRINT SHIP MASTER:

If you open the BP_ShipMaster blueprint you will see how the ship works, there are 3 timers connected to
custom events. (event tick is not used). These timers are made to start after a random delay per each ship,
to avoid them firing simultaneously. One timer is on very high frequency and it’s used for physics and spline
movement. It only works when needed, if you set a ship to “Do Nothing” the ship will not use a lot of
functions.
In the Viewport Tab you will see a large hull, propellers, rudders and other things like cameras, particle
systems, sounds.

Avoid changing things in the Master blueprint because every other ship will be affected by these changes.
Also, if you promote something to a variable from a function or the graph be sure to do it in an empty map
without other ships, otherwise the variable will be set to 0 even if in the master blueprint it’s set to a value.
So you will have to edit all the other ship blueprints and restore the variable to the default value.

HOW TO CREATE A NEW SHIP:


We did a Map to show you how to create the ship, you can open the map MAP_NewShipCreation to have a
reference.
A new ship can be created following these 10 Steps:
Create the 3d model or modify an existing 3d model. You have to split the Ship model in a specific way:
There’s a part that have to simulate physics so it must have a simple collision. You can use the collisions up
to the 26 DOP collision but don’t use the Convex Collision or you will get an error when packaging the
game.

If you want to walk on the ship with your character it’s very important, for the hull, to be flat on top.
Otherwise a simple collision will be misaligned with the static mesh and the character will seem to float.

In this example the ship is not flat:


There are two parts, one in front and one on the back of the ship that are not aligned with the hull. So, the
solution is to separate them from the HULL static mesh that will look like this:

You can also remove the upper green floor if you later add it with other static meshes like in the following
image: the upper part, that will be added to the blueprint, has already a floor so the lower part (the hull) is
without any floor and seems a bit weird because you can’t see the inside but there’s not UV in the inside
and this won’t cause any issue. Later you will cover the hull with the upper part .
Top: HULL only, bottom: upper part only. The parts that will simulate physics must use a simple collision. A
convex collision can also work. To be sure you can do a simple test, using the output log, to see if
everything works.

IMPORTANT: When you export the static mesh of the hull the pivot point is extremely important:

Take a look at the axis (RED) X and Z and try to place the hull using the X axis as if it’s the water level. Also
the Z axis should be at the center of the model and not at the sides or the ship will behave strangely when
using physics and also when following splines because the hull pivot will also be the pivot point of the Ship
Pawn blueprint. The spline following is made moving the actor on it’s pivot. So use the above image as
reference before exporting the 3d model. If you can’t set it in the 3d editor then you will need to change
the center of mass in the physics settings of the blueprint. But the movement along the spline will be a bit
weird because the ship will rotate on its pivot point.
The final result, in the blueprint, after joining the hull to the upper part will be this:

So, import the hull inside the Unreal Engine and, if enabled, the collision should be created on import.
Then import all the other parts as you prefer.
Once everything is imported you can select the BP_ShipMaster blueprint and right click to create a “Child
blueprint class”. Rename it and click to open the new child blueprint.
Go to the viewport and you will see the same hull of the BP_ShipMaster. Select the “ShipBody” component,
on the upper left of the screen under components tab and, on the right, replace the Static Mesh with the
one of your new ship.
Select the SM_Propellers_Shafts and move them in the position you want to place the propellers, rudders
etc. Just move the first component (SM_Propellers_shafts) to move all the assembly, avoid moving single
attached parts.

This assembly is made for the large cargo ship so it will be huge on the new ship, if smaller. Plus you may
want to change the propulsion type with something else. If you want to keep these propellers, rudders etc
just rescale the first component (SM_Propellers_shafts) and also the other attached components will
rescale. If you want to replace the propulsion system just select the other components, for example
SM_Propeller_L and SM_propeller_R and select a new static mesh for them or also clear the mesh if you
don’t want to use it:

As you can see in the image above we removed the static mesh of the propellers shafts (just the static
mesh, on the right is set to none). DON’T REMOVE THE COMPONENT ON THE LEFT. Then we selected the
rudders and we replaced them with these outboard motors:

They are not rudders but the rudders movement is already programmed so the engines will move like if
they were rudders. And orient in the movement direction.
Then select the propellers SM_propeller_L and SM_Propeller_R and replace them if you want (in this case
we used a double propeller per each motor)
And position them in the proper relative location just by moving them in the viewport tab.
At this point there’s the most important part: Normally the propellers are attached to the ShipBody static
mesh that is simulating physics. Attaching them to a non-physic simulating static mesh can cause issues. So,
select the C_Prop_L and C_Prop_R that are the physic constraints and change the “Component name 1” to
SM_Rudder_L or SM_Rudder_R according to the propeller (R with R and L with L). (see the image below)

If you see the blue box for the first component and the red box for the second component like in the image
above it’s ok and you can do the same with the other engine.

IMPORTANT: If you plan to use just one engine just clear the static mesh for the LEFT engine, propeller and
rudder or just move them where they are not visible, then, on the left in the variables search for “single
Engine” and set the Boolean to true. (see the submarine example)
UPDATE 1.5 – VERY IMPORTANT: Because physic constraints becomes wobbling when moved along a spline
we created a very simple system to avoid this problem. To make sure it works you have to give a TAG to
every rudder you add
“Rudder” and a TAG to every propeller you add “Propeller”. This is VERY IMPORTANT because every
propeller and rudder will be copied and a no-collision static mesh will be created. So, when the ship is
moving along the spline the non physic static mesh will be visible and the physic static meshes not. This is a
solution to the problem that constraints can’t be disabled during game and setting not to simulate physics
on a static mesh create glitches.

So, if you add another propeller and another rudder in the child blueprint be sure to add a tag to the static
meshes “Propeller” for propellers and “Rudder” for rudders.
You won’t probably notice it in game but these copies, that are automatically made, won’t wobble like if
they were using physic constraints and, when the ship moves using physics the normal, physic simulating
meshes are again used.
In this case we just moved the other propeller (the left one) inside the submarine body and set the
“singleEngine?” Boolean to true.
It’s very important because the force of the physic based movement is given to the propellers so, if you
have just one propeller and you set the single engine Boolean to true the force will be entirely given to the
RIGHT PROPELLER. So, if you move the right propeller to the center of the body instead than the left 1) it
won’t rotate 2) the force will be applied in the wrong position.

As said you can also clear the static mesh on the right if you don’t want an unused propeller in the middle
of the ship:
For the rudders, in the example of the submarine, one rudder is on top and the other one is on bottom,
both are replaced with a new static mesh and also the propeller shafts is replaced with another static mesh:

At this point you can add other static meshes, like the turret of the submarine and to do this just SELECT
The SHIPBODY component and then in the green tab select “ADD COMPONENT” and static mesh
component:
Then select the component you have imported and check for the collision:

Because the vehicle collision is used to block other ships and this component won’t be simulating physics
it’s better to select object type “Vehicle” and disable the Object response to the Vehicle like in the above
image. You can also try to leave the collision to vehicle active but if you see weird movements when the
ship is on the waterplane it can be caused by a collision problem. So Custom collision > Object type vehicle
> disable vehicle collision response.
You can also disable the collision if you don’t need it.

At this point the basic static mesh setup should be done, you can now start to edit the variables that are
used to move the ship:
In the search tab on the left type “MAX” and check for “MAXWantedMoveForward”. This value, float type is
used to increase the acceleration time and deceleration time of the ship. It’s like, for example, a pool. The
move forward input is a bucket of water, the “MAXWantedMoveForward” is like the pool volume. By
default this is set to 50. So, to go to full move forward you will need more bucket of water. If you set it to
20 like in this case it will accelerate more quickly.
Take a look at the second float MAXPhysic_MF_increment. This is the bucket of water volume of the pool
example. If you set this to .01 it will take longer to go to full move forward and longer to go to zero move
forward. So longer acceleration times and longer deceleration times.

Then you can search, in the left bar, for “stabilization”


These are the pitch and roll stabilization forces. They are very important because otherwise the ship could
pitch and roll too much. In a small ship like the RHIB too much pitch will mean that the water will appear
inside the ship when accelerating.

Ideally it’s better to increase the pitch stabilization or to cover the rear part of the ship to avoid seeing
water inside the boat.

UPDATE 1.5: We’ve added a variable that is an offset to better select the point where the propulsion force is
applied. Otherwise the force was applied to the propellers location. But if the propeller is very low or very
high respect the pivot of the ship the propulsion force will give too much pitch inclination. So, search for
“UpVectorForceOffset” a float variable and give it a number like -100 and test the ship. If the value is
negative the ship should pich less (the bow will be down) if the value is positive the ship would pitch more.
An example of this new feature is in the hovercraft that, because of the propellers on top, was moving with
the bow too down and it was not realistic.
Speed Settings:

In the left bar, like before, search for “speed knots” and look at the variable, of float type,
“MaxSpeedKnots” this is the max speed of the boat, in knots. Consider that a knot it’s about 1,852 km/h or
1,15078 miles/h
A ship that reaches 40 knots may seem slow in the game but it’s a nice speed in the real world. We used
knots because it’s the standard for ships. This settings also affects the speed on the spline.
In the search bar, search for “propellers” and you should see this float variable:

“PropellersSpeedMultiplier” is used to make the propellers to spin more quickly. It won’t affect the
movement, it’s just a cosmetic adjustment.
To make the ship go faster you can search for “speedcustommultiplier” that is by default 100, increasing
this will make the force that pushes the ship stronger. This can also require adjustments to the pitch and
roll stabilization because it will pitch much more

SEA LEVEL:
If your hull 3d model has been exported correctly you won’t need to adjust this value, but if you see that
the ship is floating above the water then you can adjust the “Ship_SeaLevel_Z_Offset” float variable (look
under initial settings.

ManuallySetSeaLevel_Z can be used to manually adjust the Z location of the ship but it shouldn’t be
something you will have to care because the ship can be drag and dropped in the scene, if there’s at least
ONE BP_ShipRoute blueprint in the level.
To avoid referencing the water plane in the ship we used the ship route to get the Z location of the
waterplane. If you don’t have a ship route in the level you will have to manually adjust the Z location of the
ship. Once done, if you start play, the water should be at the level initially set.

“CanThisShipBeUsed?” Is a variable that prevents the interface to list the ship as drivable. This can be used
if you have ships that are there just for the scene and you don’t want the player to use them.

STEERING TORQUE:
On certain ships, if the speed multipliers are high, the steering can be too strong and the ship will spin. This
can be fixed by increasing the angular damping of the shipbody static mesh. (select the ShipBody
Component in the viewport tab of the blueprint and on the right, under physic settings, increase the
angular damping value”
In other cases the ship could be very slow to turn, in this case you can enable the Boolean “add Additional
Steering Torque?” and assign a value to the “additionalSteeringTorqueMultiplier” float variable. This will
help the ship to steer and it’s also important for the AI to reach the locations correctly when using physics
to move.

FINTERP:
It’s possible to interpolate several forces, like the steering torque or the propulsion force or buoyancy force
to avoid spikes but this will cost some performances and you will need to adjust the finterp speed to avoid
having an irresponsive ship hard to control or a wobbling ship.

UPDATE 1.5: We’ve added the possibility to use the even tick only for spline moved ships that you need to
use to carry a character. Using the timer, also with a very high frequency, caused a not-smooth movement.
Instead with the event tick, only used for this particular situation (all the other movement, like physic based
are still using the timer).

This is very important because otherwise the character on the ship that is following a spline, like the ferry
will move like by small steps and it’s visible and not very realistic. Using the event tick just for this particular
situation works. Probably you will lose some performance but if you use the ship to carry characters it’s
fundamental.
As you can see there’s also the possibility to disable the use of event tick if you don’t plan to use the
character camera when they are carried by a spline moving ship.

It’s also possible to increase the use of the event tick also for rotations performed by the ship that are not
using physics. To do that, in the branch AINewStance = follow spline you can add an “OR” and also
AINewStance= Align To Point and do the same in the branch after the event tick to disable it and use the
HFT timer below.

Harbour HIT Return Impulse:

When the ship hits the harbour with physic simulation enabled it will receive an impulse in the direction of
the hit that will make the ship bounce back. It’s useful because if the ship is against a wall with its side
nobody can push the ship away from the wall and engines and rudders will push the ship against the wall.
So having a hit return impulse will help you to not get stuck against an harbour wall. However consider that
a value too high will make the ship fly away after hitting the port walls.

SUBMARINE:

The Boolean variable “CanGoUnderwater?” is used to make the ship float below the sea level. You can also
adjust the “submarineimmersionspeedMulti” to increase the speed.

HOVERCRAFT:

Like with the submarine the hovercraft can go above the sea level, in this case you have to enable the
variable “IsHovercraft?” and the Hovercraft_FloatSpeedMulti to increase the speed used by the hovercraft
to climb.

IMPORTANT: Hovercraft and submarines are made using the ship floating system. This is not an hovercraft
or submarine simulator so they have limits because the logic is made for ships.

ANCHOR SYSTEM:

If you add and rescale the anchor blueprint to a ship, like in the cargo ship, you can have the possibility to
use anchors to steer the ship.

If you drop one anchor only, for example the right anchor, the ship will tend to steer left if going forward
and right when going backward, without using the rudders.

If you drop both the anchors the ship won’t move.

The anchor chain system is quite complex, it’s based on hierarchically instanced static meshes, using a small
segment of the chain and creating and moving many instances of the segment.
As you can see there are two different chains because one is on the deck of the ship and it’s visible, it’s
connected to the winch system. So this chain is moved like a real chain. Originally this was the only system
to animate the anchors but consider that moving a 100 instances is not such a problem for performances,
but moving 1000 instances can become a problem and create some FPS drops. To avoid this we split the
anchor chain, one is just moving on the deck, changing the transforms of the chain segments along a spline.
The other one instead is creating and destroying instances, the result of the second one is less accurate
than the result of the first one. But it’s good for performances and a lot of the chain will be below the sea
level and won’t be visible.

You can change the anchors static meshes with other, just check for the pivot that should be on the top ring
of the anchor. You can also change the chain and the length of the segments.

This actor can also be rescaled and applied to other ships.

SHIP AI:
The ship are not using AI Controllers because they rely on the nav mesh bounds. So we added a blueprint
system that is made using steps. It’s very easy to setup and to expand. You can see it inside the
BP_ShipMaster > “M_NewAILogic”. There are a lot of spaghetti because it’s a macro so the wires are
necessary but we couldn’t use a functions because there are some delays in the macro and a function can’t
use delay.
The system is using steps. Steps are user set commands you can choose with an enumerator and insert in
an array of commands.

If you select a ship on the Demo map you can see a list of these commands under the AI tab of the details
panel.

For example the ferry uses 7 commands:

Find a ferry route right > Go To Location Using Physics > Follow Route > Stop for 5 minutes > Reverse on the
same spline of the same route > Follow route > stop for 5 minutes > repeat cycle

And the variable (integer) Repeat the cycle start step is set to 4

See the image, on the left there are the programs:


This means that the ship will look for a ferry route and will choose the right side of the route. Then will go
there using physics.

IMPORTANT: After giving the command “Find a route etc” you MUST add the command
“GoToLocationUsing Physics” otherwise the ship will just find the route and will not go there. Also, after
using the GoToLocation always use the follow route command or the ship won’t follow the spline.

Basically you can add as many steps you want but it’s not necessary if the operations are looping using the
repeat cycle. Repeat cycle will repeat the cycle of commands from the Step 0 if not specified differently
using the Repeat the cycle start step.

So, in the example above the cycle will restart from step 4 instead than 0. Step 0,1,2,3 are used only after
the game starts but, once the route is found and the ship is in position, there’s no need to find the same
route again.

This Is the list of all the commands that we have added as default but you can also add new commands:

To add a command you can add an entry in the enumerator E_NewShipBehaviour and then, in the
M_NewAiLogic of the BP_ShipMaster, use the switch to add the logic for this step.

Due to the fact that programming every ship can be boring a slow we have also created a pre-programming
system that uses a data table. Basically you can create programs manually, test them, then go to the data
table DT_PremadePrograms and add a new row. Also add a new entry to the E_PremadeProg enumerator
that defines the name of the command list.

So, drag and drop a ship inside the port of the demo map, go to the detail panel, go to AI LOGIC and check
USE AI BEHAVIOUR > check USE PREMADE AI PROGRAM > Select the Premade Program TO use and the ship
is programmed to make a list of operations you will see in the Premade AI behaviour structure below.
We think that this system can be very useful to quickly assign tasks to the ships. Also using the data table
will allow to create an infinite amount of program combinations.

Just be sure to respect the Logic of the step system: After Find route > Go To Location, after Go To Location
> Follow route because the go to location won’t make the ship follow the route automatically.

AVOIDANCE:
Because you can have many ships we have added two different Avoidance systems. One is used when the
ship is moving using physics, the other one is used when the ship is on a spline following it.

The physic based avoidance will detect a ship and then change direction to avoid the hobstacle. The spline
based avoidance will make the ship stop, if there are no other possibilities, or to use the splines that are
added to every route to overtake the other ship or to simply avoid a front collision.

The system is inside the BP_Ship Master blueprint under M_Avoidance macro.

It’s difficult to create a perfect avoidance system because every operation should be repeated continuously
and you might have a lot of ships in the level. So the hardest part is to reduce the quantity of traces and
calculations without creating dumb AI ships that will collide.

DOCKING:
We have created a simple actor, BP_DockingPoint that can also be included in the port blueprint. It uses a
custom object channel that is, by default, on ignore.

So the ship that wants to dock will trace for this channel, if it finds a docking actor the ship will check if the
docking space is big enough for the ship size. If it’s ok the ship will dock there and stop.

Docking points can be seen in the Demo Map as green or orange boxes. The color is used because a docking
point can be free for all or just for commercial ships.
You can specify the type of docking space, if it’s free, and the size of the docking space that will determine
the max ship size for that docking spot.

RADAR:
If you use the UI that comes with the project you will be able to see the radar minimap. It’s a simple render
target of low resolution, with altered colors. To use the radar you can add the actor as a child component
on every ship. If your ship has already a radar pole you can just move the child actor component to the
radar pole. If not you can, under details of the child actor, set the visibility to true for the radar pole.

The radar will work automatically and will display a minimap in the ship hud. It will also rotate the radar
static mesh and you can decide the rotation rate.
SONAR:
The sonar or depth finder is an actor component that, by default, is already added to the BP Ship master
blueprint. It’s used to measure the depth of the water in front or behind the ship. It’s useful if you want to
implement some sort of alarm to stop the ship from going in shallow waters.

It also renders a graph with the depth that the ship found in the last 5 minutes or so.

You might also like