Ingame Date & Time

This UE4 plugin provides functionality for working with calendar dates and times within your game.

The idea is to configure a game-internal date system, which can either use the standard calendar or a custom made calendar. You can then schedule Blueprint/C++ timers using dates, times and durations specified in your internal game calendar. This removes the need for constantly converting between real time and game time in your calculations and scripts.

Getting Started

Once the plugin is installed, the classes are immediately available for use.

A good starting point is to look at the examples contained in IngameDateTime Content/Examples. To see this, you may need to go to View Options in the content browser and enable Show Plugin Content.

Note: the following is an overview of the available functionality. In many cases a more detailed explanation of a function will be given in the node reference, also available in the Documentation directory of the plugin. The same information is exposed via tooltips in the blueprint editor. All functions are tagged with the category ‘Ingame Date & Time’, so right clicking on a blueprint graph, unchecking Context Sensitive, and typing in ‘Ingame’ is a good way to see what is available and find the associated tooltip explanations.

Examples

Two example calendars are included, each with their own basic demo map.

Both demos share a UI designed to showcase the functionality of the plugin, so you can modify the realtime clock rate, load/save clock state, and enter timed message events specified using the ingame calendar. Of course, in practice, you will generally be interfacing with the system from your blueprints/code rather than providing a UI.

The examples also show how to create UMG widgets for displaying the time.

Gregorian

This example uses the standard calendar. It has a simple level set up with a directional light for the sun, a sky sphere, and a pole casting a shadow over a landscape. The blueprints in the LevelEntities/SunSource folder give an example of how the clock can be hooked up to a visual time of day system.

Stardate

This demonstrates use of a custom-defined calendar. In this case, we have year, day (200 days in a year), hour (26), minute (60), second (60).

Setting up your calendar and clock

The basic setup steps are as follows:

  1. Create a blueprint, based on either GregorianCalendar (for a standard calendar) or FixedPeriodCalendar (for a custom calendar). Configure properties as desired. (Note: the plugin class GregorianCalendar can in fact be used as-is, however I recommend always creating your own blueprint based on the C++ class, in case you later want to adjust some properties).
  2. Create a blueprint based on IngameClock, set its Calendar Type property to your calendar blueprint. Adjust other properties if desired.
  3. If you don’t already have a custom GameState blueprint/class, create one and make sure it is set to be used by your game mode.
  4. Add an IngameClock component to your game state. Set its Clock Class property to the clock blueprint you created in step 2.

Once that’s done, your clock will automatically be initialized at level startup. If you want to set the clock time at that point, you can override the OnInitialized event inside your clock blueprint.

To access the clock and calendar, use the functions GetGlobalIngameClock and GetGlobalIngameCalendar. If you have blueprints that need very frequent access, it is better to call these only during BeginPlay, and store the result in a variable on your blueprint.

Core concepts

Date/Time

A date/time is composed of a value for each time period in a given calendar.

Partial date

A partial date is used to specify a recurring point in time. For example, Jan 1st, 00:00:00 is a partial date where the year is left unspecified. Likewise, 30:00 is a partial date repeating at half past every hour.

Duration

A duration represents a period of time, and can only be composed of units of fixed length. For example, in the Gregorian calendar class, durations are some number of days, hours, minutes and seconds. Years and months are not permitted, since they are not of fixed length.

Formatting

There are various functions provided by the calendar classes for formatting times and dates. For maximum flexibility, FormatTimePeriodValue can be used to format a string for time periods individually. You can then construct UMG widgets with separate text blocks for each period, allowing different fonts and effects for each part. This is the approach used in the Stardate example - see WBP_StardateComplete:GetYearText/GetDayText.

A more compact way is to use the FormatTime function. You can insert any time period IDs you like into the format string. For example, WBP_StardateComplete:GetTimeText passes the following: {Hour|w2|z}:{Minute|w2|z}:{Second|w2|z}.

Formatting specifiers can optionally follow the period ID, separated by ‘|’s.

Current options are:

w[x]

Fixed width, where x is an integer specifying the width in characters, eg w2

z

Prefix leading zeros rather than spaces to fill out the desired width.

The Gregorian calendar has some extra formatting tags, described at the end of this document.

There is one special unit tag for outputting the fractional part of a time. This is specified in the format string as {f[x]}. For example: {Second}.{f2} for 2 decimal points.

There are also functions for formatting durations. FormatDurationSimple will use a standardized form, whereas FormatDuration behaves like FormatTime, accepting a format string specifying which time periods should be used. It differs in that it will break down the duration depending on what combination of units are given, starting with the largest unit and ending with the smallest such that the entire duration is accounted for.

String input

When specifying a date/time or duration as a string, the structure depends on what exactly you are specifying (a date, a partial date, or a duration). How you configure the Date Input Separator and Duration Input Separator properties on your calendar also determine how to format an input string.

As an example, the Stardate calendar is setup to accept the following input formats:

Date/Time: y.d-h:m:s

Duration: d:h:m:s

Not all periods need be specified, but note that dates and durations are treated differently in this case. For example, an input of 1.1 for a date in the Stardate calendar is treated as year 1, day 1, with the smaller units (hours, minutes, seconds) assumed to be zero. On the other hand, a duration input of 1:1 means 1 minute, 1 second. Dates are parsed from the left (most significant unit), durations from the right (least significant unit).

Persistence

Adding the state of a clock to a UE4 SaveGame object is very easy - see Examples/Common/Saving/BP_ExampleSaveGame and Examples/Common/Widgets/WBP_SaveLoad.

If you need a clock to persist between levels, you will need to grab its state in the same way, and then reload it into the clock in the newly loaded map. Essentially this is the same process as above, except instead of a SaveGame object, you would likely want to store the state temporarily on your GameInstance.

Gregorian Calendar Extensions

Additional Functions

MakeSystemUTCTime will create a time value based on the system clock current time (UTC time is equivalent to GMT - the plugin has no built in support for time zones).

GetDayOfWeek creates an enum value representing the day of the week, from the given time.

GetNextWeekday can be used to find, for example, the time representing the next Sunday following a given.

CalculateSunPosition takes a latitude, longitude and UTC time, and generates elevation and azimuth angles defining the precise position of the sun.

Special Formatting Options

The following tags can be added to adjust formatting. These are appended to the unit specifier in the format string, separated with a ‘|’. For example, {Year|yyyy}. They can also be added to the FmtTags array in the UnitValueFormatOptions struct when using the FormatTimePeriodValue function.

Unit

Tag

Meaning

Year

yyyy

Format width is 4 characters, padded with spaces not zeros.

yy

Width is 2, century is omitted.

Month

mmmm / long

Long month names (eg. January)

mmm / short

Short month names (eg. Jan)

mm

Width 2, leading zeros.

m

Width 2, padded with a space not a zero.

Day

dd, d

As above.

Hour

hh, h

12

12 hour clock format.

Minute

mm, m

Second

ss, s

Two further format specifiers are also defined:

Specifier

Optional tags

Meaning

{ampm}

upper

Outputs either “am” or “pm”, in uppercase if upper tag is added.

{dow}

short

Outputs day of the week, full form by default.