User Tools

Site Tools


manual:subwaysim:map_construction:create_maplua

This is an old revision of the document!


Map.lua

The Map.lua file defines all runtime logic for a map in SubwaySim 2.

It is responsible for:

  • registering the map in the ContentManager
  • linking the Unreal Engine level to the map
  • defining stations and platforms
  • loading AI timetables and services (see timetable guide)
  • configuring dispatching and depot logic
  • providing optional career mode data

This page explains the structure and purpose of the Map.lua file and how it interacts with elements placed in the Unreal Editor (tracks, signals, Station Definitions).


Purpose of the Map.lua

The Map.lua acts as the central configuration and logic file for a map.

While the Unreal level defines the physical layout (tracks, stations, signals), the Map.lua defines the operational behavior:

  • where trains may spawn
  • how they route through the map
  • which stations exist and how they are used
  • when and how AI services operate

Without a Map.lua, a map:

  • cannot be selected in the menu
  • cannot spawn AI trains
  • cannot provide station-based logic

Prerequisites

Before working with the Map.lua, make sure that the following steps are completed:

  • The Unreal level (.umap) is finished

Create a Level

  • Tracks and signals are correctly placed

Railtool

  • BP_StationDefinition actors exist for all stations and depots

Prepare a Map for SubwaySim

  • Platform numbers, platform lengths, and platform directions are finalized

(these values are referenced directly by the Map.lua and must not change later)

The Map.lua relies on these elements being set up correctly and consistently in the level.


Map.lua Explained (TestMap Example)

This page explains the structure of a Map.lua file for SubwaySim 2. It follows the file from top to bottom and explains each section in detail.

The Map.lua consists of two major parts:

  • Map Registration (ContentManager DataTable)
  • Runtime Map Logic (Lua class based on BaseMap)

Complete Map.lua File

--
--
-- SubwaySim2
-- Module TestMap.lua
--
-- Map file for SDK TestMap
--
--
-- Author:	SDK User
-- Date:	__/__/____
--
---@class TestMap : TestMap, BaseMap
TestMap = Class("TestMap", TestMap, BaseMap);
 
---@type SSB_Map_DataTable
local TestMap_DataTable = {
	contentType		= "map",
	contentName		= "TestMap",
	class			= TestMap,
	levelName		= "Testmap",
	author			= "$GameDeveloper",
 
	title			= "SDK TestMap",
	subtitle		= "This could be your text",
	description		= "This is a test map that demonstrates how to use the Modding SDK. You can also use it for testing your own vehicles.",
	previewFilename = "/SubwaySim2_Core/UI/MainMenu/Backgrounds/CityBerlin.CityBerlin",
};
g_contentManager:addContent(TestMap_DataTable);
 
--- Creates a new instance of this class
---@return TestMap
function TestMap:new()
	self = TestMap:emptyNew();
 
	self.levelName		= "Testmap";
	self.displayName	= "SDK TestMap";
 
	-- latitude and longitude of Berlin's city center
	self.latitude		= 52.518611;
	self.longitude		= 13.408333;
	-- UTC+1
	self.timezone		= 1;
 
	self:loadStations();
 
	-- Timetables define AI service patterns.
	-- Full guide: manual:subwaysim:map_construction:create_timetable
	self:loadTimetables();
 
	self:loadCareerMode();
 
	EventManager.callModListeners("onMapCreated", self);
 
	return self;
end;
 
--- Event to load any additionally required level instances
function TestMap:loadLevelInstances()
	assert(GameplayStatics.loadLevelInstance("SubwaySim2_Environment", Vector3.zero, Vector3.zero), "Failed to load a part of the level");
end;
 
--- Loads the station definitions for this map
function TestMap:loadStations()
	---@type table<string, Station>
	self.stations = {}
 
	self.stations.TS = Station:new("TS", "TestStation")
		:addSpawnPlatform("1", 115, 2)
		:addSpawnPlatform("2", 115, 2)
 
	self.stations.TSD = Station:new("TSD", "TestStation Depot")
 
	self.stations.TSA = Station:new("TSA", "TestStation Anfang")
		:addSpawnPlatform("1", 110, 1)
		:addSpawnPlatform("2", 110, 1)
 
	self.stations.DP = Station:new("DP", "Depot")
		:addSpawnPlatform("51", 220, 2)
		:addSpawnPlatform("52", 220, 2)
		:addSpawnPlatform("53", 220, 2)
		:addSpawnPlatform("54", 220, 2)
		:addSpawnPlatform("60", 110, 2)
 
end
 
--- Loads the default timetables for this map
--- Full guide: manual:subwaysim:map_construction:create_timetable
function TestMap:loadTimetables()
	-- (Implementation depends on your map and service patterns)
end
 
--- Initializes data for career mode
function TestMap:loadCareerMode()
end;
 
--- Registers all valid timetables to the given `controlCenter` instance
---@param controlCenter ControlCenter
function TestMap:registerTimetables(controlCenter)
	controlCenter:setStationList(self.stations);
	controlCenter:setTimetableList(self.timetables, self.dispatchingStrategies, self.depots);
end;

1) Map Registration (ContentManager DataTable)

The DataTable registers the map in the ContentManager. Without it the map will not appear in the map selection menu and cannot be loaded.

DataTable Fields

Field Description
contentType Defines the type of content. Must be `“map”`.
contentName Unique internal identifier for this map across all mods.
class Reference to the Lua map class that provides runtime logic.
levelName Unreal level (.umap) name that will be loaded. Must match exactly.
author Author metadata (UI / debugging).
title Map title shown in the selection menu.
subtitle Optional subtitle below the title.
description Longer description shown in UI.
previewFilename Path to the preview image used in the main menu.

Registering the DataTable

After the table is defined, it must be registered:

g_contentManager:addContent(TestMap_DataTable);

If this call is missing, the map is not registered and will never load.


2) Runtime Map Class (BaseMap)

The runtime class is responsible for everything that happens when the map is loaded:

  • defining stations and their platforms
  • loading timetables and AI services
  • configuring dispatching / turnaround rules
  • optional career mode setup

Class Definition

TestMap = Class("TestMap", TestMap, BaseMap);

This creates a new map class inheriting from `BaseMap`.


3) Constructor (new)

The constructor creates the map instance and prepares the runtime data.

Core Properties

Property Description
self.levelName The Unreal level to load (must match DataTable `levelName`).
self.displayName Internal display name used at runtime.
self.latitude Used for sun position and environment lighting.
self.longitude Used for sun position and environment lighting.
self.timezone Timezone offset for day/time simulation (UTC+1 = 1).

Loading Runtime Data

The order matters:

  • `loadStations()` must run first (timetables reference stations)
  • `loadTimetables()` defines AI services and dispatching/depot logic
  • `loadCareerMode()` is optional

Mod Event Hook

EventManager.callModListeners("onMapCreated", self);

This allows other mods or systems to react when the map instance is created.


4) loadLevelInstances()

GameplayStatics.loadLevelInstance("SubwaySim2_Environment", Vector3.zero, Vector3.zero)

This call loads the shared environment level used by SubwaySim 2.

It provides:

  • weather effects (e.g. rain)
  • global lighting
  • time-of-day behavior

By loading this prepared level, mod maps can use the full weather and lighting system without accessing license-protected core code.

⚠️ Current limitation: Loading multiple levels that contain Railtool Blueprints can cause issues. At the moment, only one loaded level should contain Railtool infrastructure. This limitation will be resolved in future updates.


5) Stations (Derived from BP_StationDefinition)

Stations defined in `loadStations()` must match BP_StationDefinition actors placed in the Unreal Editor.

5.1 How Lua Stations Connect to BP_StationDefinition

The connection is made via the station short name:

  • In Unreal: BP_StationDefinition → Name Short
  • In Lua: `Station:new(“TS”, “TestStation”)`

If the short name does not match exactly:

  • stations may not register correctly
  • AI routing can fail
  • timetable stops may not resolve

5.2 Station Table

Stations are stored as a keyed table:

---@type table<string, Station>
self.stations = {}

The key is usually identical to the short name:

  • `self.stations.TS`
  • `self.stations.TSA`
  • `self.stations.DP`

5.3 Station:new()

Creating a station:

Station:new("TS", "TestStation")
Parameter Description
`“TS”` Short name (station code). Must match BP_StationDefinition Name Short.
`“TestStation”` Display name shown in UI.

5.4 addSpawnPlatform()

Spawn platforms define where trains may spawn for player spawning (depending on map setup)

Example:

:addSpawnPlatform("1", 115, 2)
Parameter Description
`“1”` Platform number as defined in BP_StationDefinition platform array.
`115` Max allowed train length in meters for spawning at this platform.
`2` Spawn direction on the track (orientation). Must match your platform Begin/End marker direction logic.

⚠️ Important Platform numbers are not “free”. They must match exactly the platform configuration inside BP_StationDefinition.


6) Timetables (Overview)

Timetables define the AI service pattern on a map (which trains spawn, where they stop, and when they run).

In Map.lua, timetables are typically created inside:

  • `function <MapClass>:loadTimetables()`

This function usually initializes:

  • `self.timetables` (the final list of actual services)
  • timetable templates (often per line and direction)
  • optional tables like `self.templatesByLine` / `self.templatesByDirection`
  • depot definitions (`self.depots`)
  • dispatching strategies (`self.dispatchingStrategies`)

The full workflow and all timetable features are explained here:


7) Career Mode (Optional)

Career Mode is optional. If you don’t want career mode features on your map, you can leave `loadCareerMode()` empty.

If you *do* want career mode, this function defines:

  • where the player is allowed to take over a train
  • optional route closures (for scenario logic)
  • which train compositions the player is likely to get
  • which timetable templates are used for pathfinding

(Example implementations are map-specific.)


8) Registering Stations and Timetables

The final step is registering runtime data with the ControlCenter:

controlCenter:setStationList(self.stations);
controlCenter:setTimetableList(self.timetables, self.dispatchingStrategies, self.depots);
Call Description
setStationList Registers all stations for routing, UI and spawning logic.
setTimetableList Registers AI services plus dispatching and depot logic.

If this function is missing or incomplete:

  • AI traffic will not work
  • stations may not be recognized for routing

Final Step – Build & Test the Map

Continue with:


Additional Resources


© 2025 Simuverse Interactive · SubwaySim 2 Modding Wiki

All trademarks and registered trademarks are the property of their respective owners. This Wiki is provided for documentation and modding purposes only.

2025/12/12 12:06 · dcs
manual/subwaysim/map_construction/create_maplua.1769509130.txt.gz · Last modified: by dcs

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki