User Tools

Site Tools


manual:subwaysim:map_construction:create_timetable

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
manual:subwaysim:map_construction:create_timetable [2026/01/27 11:20] dcsmanual:subwaysim:map_construction:create_timetable [2026/01/27 11:26] (current) dcs
Line 14: Line 14:
 This page explains the full **timetable workflow** using the TestMap example. This page explains the full **timetable workflow** using the TestMap example.
  
-Related: +Related: [[manual:subwaysim:map_construction:create_maplua|Create Map.lua]]
-  * [[manual:subwaysim:map_construction:map_lua|Map.lua]]+
  
 ---- ----
Line 49: Line 48:
 ---- ----
  
-===== Step 1 — Create Templates (Per Line & Direction) =====+===== 6Timetables =====
  
-Templates describe the route and the allowed compositions, but do not spawn trains by themselves.+Timetables define: 
 +  * which trains spawn (compositions) 
 +  * what route they drive (stops) 
 +  * on which platforms they stop 
 +  * how often services repeat
  
-Example:+==== 6.1 Timetable:new() ==== 
 + 
 +A timetable template is created with:
  
 <code lua> <code lua>
--- Direction 1 (TS -> TSA) +Timetable:new("U1", 0)
-self.TestLine_Dir1 = Timetable:new("U1", 0+
- :addTrainComposition("Berlin_HK_1x", 0.5) +
- :addTrainComposition("Berlin_HK_2x"+
- :addTrainComposition("Berlin_A3L92_1x", 0) +
- :addTrainComposition("Berlin_A3L92_2x", 0) +
- :addTrainComposition("Berlin_A3L92_3x", 0.5) +
- :addTrainComposition("Berlin_A3L92_4x")+
 </code> </code>
  
Line 70: Line 68:
 | `0` | Variant / index value (map-specific usage). | | `0` | Variant / index value (map-specific usage). |
  
-----+Templates are usually created per direction: 
 +  * Direction 1: TS → TSA 
 +  * Direction 2: TSA → TS
  
-===== Step — Add Stops (Route Definition) =====+==== 6.Train Compositions ====
  
-Stops define the route as a sequence of station/platform/time entries.+Train compositions define **which vehicle sets may be used** when this timetable spawns AI trains. 
 + 
 +Each composition is referenced by its `contentName`, exactly as it is registered in the 
 +ContentManager (e.g. in `Vehicle.lua` or `Composition.lua`). 
 + 
 +Example: 
 +  contentName = "Berlin_HK_2x" 
 + 
 +The name must match **exactly**.   
 +If composition is not registered or the name is incorrect, no train will spawn for it. 
 + 
 +==== Adding Compositions to a Timetable ==== 
 + 
 +Compositions are added directly to the timetable template: 
 + 
 +<code lua> 
 +:addTrainComposition("Berlin_HK_2x"
 +</code> 
 + 
 +A weight can optionally be provided: 
 + 
 +<code lua> 
 +:addTrainComposition("Berlin_HK_1x", 0.5) 
 +</code> 
 + 
 +If no weight is specified, a default weight of `1.0` is assumed. 
 + 
 +==== Composition Weights ==== 
 + 
 +Weights control how likely a composition is selected **relative to other compositions** 
 +within the same timetable. 
 + 
 +They only affect **AI spawning behavior** for this timetable. 
 + 
 +^ Weight ^ Meaning ^ 
 +| **1.0** | Standard usage. The composition is commonly selected. | 
 +| **0.5** | Reduced probability. The composition is used less frequently. | 
 +| **0.0** | The composition is excluded from AI spawning for this timetable. | 
 + 
 +==== Important Behavior of Weight = 0.0 ==== 
 + 
 +A weight of `0.0` prevents the composition from being selected when AI trains are spawned 
 +by this timetable. 
 + 
 +The composition itself remains a valid registered vehicle and may still: 
 +  * exist in the content system 
 +  * appear in the vehicle selection menu 
 + 
 +This behavior is intentional and allows a composition to be: 
 +  * available to the player 
 +  * but excluded from AI traffic on a specific line or timetable 
 + 
 +==== 6.3 addStop() (Route Definition) ==== 
 + 
 +Stops define the actual route of a timetable. 
 +Each stop is a table passed into `addStop({ ... })`. 
 + 
 +Example:
  
 <code lua> <code lua>
Line 94: Line 151:
 | altPlatform | table<string> (optional) | Alternative platforms that may be used if the primary platform is unavailable. | | altPlatform | table<string> (optional) | Alternative platforms that may be used if the primary platform is unavailable. |
  
----- 
  
-===== Step 3 — Alternative Platforms (altPlatform=====+==== 6.4 altPlatform (Alternative Platforms) ====
  
 Example: Example:
Line 104: Line 160:
 </code> </code>
  
-Use strings (`"1"`, `"2"`) because platform identifiers are commonly handled as strings in dispatch/routing.+⚠️ Use string values (`"1"`, `"2"`) because platform identifiers are typically handled as strings in routing/dispatch contexts.
  
-----+This allows AI to select another platform if: 
 +  * the preferred platform is blocked 
 +  * dispatching assigns an alternative
  
-===== Step 4 — Composition Weights =====+==== 6.5 routeSettingMaxETA (Route Pre-Setting) ====
  
-Weights control probability of selecting a composition for AI spawning.+Example:
  
-^ Weight ^ Meaning ^ +<code lua> 
-| 1.0 | Standard usage | +routeSettingMaxETA = 0.5 
-0.5 | Reduced probability | +</code>
-| 0.0 | Excluded from AI spawning in this timetable |+
  
-A composition with weight `0.0` can still exist in the content system and be selectable for the player.+Meaning: 
 +  * the route will be requested/updated roughly **0.5 minutes before departure**
  
-----+This can help avoid early route locking and improves traffic handling at busy stations.
  
-===== Step 5 — Create Real Services (clone + DayMask) =====+==== 6.6 clone() + DayMask (Creating Services) ====
  
-Templates must be cloned into real timetable entries.+A timetable template does not spawn trains by itself.   
 +It must be cloned into **real timetable entries** and inserted into `self.timetables`. 
 + 
 +For day-based schedules, use `DayMask`:
  
 <code lua> <code lua>
Line 136: Line 197:
 | DM.Always | Every day | | DM.Always | Every day |
  
-==== 5.1 Repeating Interval Services ====+The typical workflow is: 
 +  * Create a timetable template (e.g. `self.TestLine_Dir1`) 
 +  * Clone it for a start time (optionally with a day mask) 
 +  * Either insert a single trip, or generate a repeating service 
 + 
 +==== 6.6.1 Repeating Services (Interval Based) ==== 
 + 
 +This creates a repeating service between two times:
  
 <code lua> <code lua>
-TableUtil.insertList(self.timetables, self.TestLine_Dir1:clone(daytime(04, 30)):repeatUntil(daytime(23, 30), 10)); +TableUtil.insertList( 
-TableUtil.insertList(self.timetables, self.TestLine_Dir2:clone(daytime(04, 35)):repeatUntil(daytime(23, 35), 10));+ self.timetables, 
 + self.TestLine_Dir1:clone(daytime(04, 30), DM.Weekdays):repeatUntil(daytime(23, 30), 10) 
 +); 
 + 
 +TableUtil.insertList( 
 + self.timetables, 
 + self.TestLine_Dir2:clone(daytime(04, 35), DM.Weekdays):repeatUntil(daytime(23, 35), 10) 
 +);
 </code> </code>
  
 ^ Call ^ Description ^ ^ Call ^ Description ^
-| clone(daytime(HH, MM), DayMask) | Creates the first entry at a given time (filtered by day mask if provided). |+| clone(daytime(HH, MM), DayMask) | Creates the first entry at a given time (filtered by the day mask). |
 | repeatUntil(daytime(HH, MM), interval) | Repeats every X minutes until the end time. | | repeatUntil(daytime(HH, MM), interval) | Repeats every X minutes until the end time. |
 | TableUtil.insertList(list, result) | Inserts all generated entries into `self.timetables`. | | TableUtil.insertList(list, result) | Inserts all generated entries into `self.timetables`. |
  
-==== 5.2 Single Manual Trips ====+Result: 
 +  * a full service pattern is generated automatically 
 + 
 +==== 6.6.2 Single Timetable Entries (Manual Trips==== 
 + 
 +If you want to schedule **individual trips** (first/last train, gaps, special runs), 
 +insert a single cloned entry:
  
 <code lua> <code lua>
Line 155: Line 236:
 </code> </code>
  
-Use this when you need exact control (first/last train, gaps, specials).+This creates exactly one departure at the given time.
  
-----+Use this approach when you need full control over: 
 +  * exact departure times 
 +  * exceptions or gaps 
 +  * different patterns on different days
  
-===== Step 6 — Useful Variations ===== 
  
-==== 6.1 Short Runs (Start/Terminate Early) ====+==== 6.7 Useful Variations (Based on the TestMap) ====
  
-Terminate at `TSD`:+The following patterns are commonly used when building more advanced schedules. 
 +They are shown here using the **TestMap stations** (`TS`, `TSD`, `TSA`, `DP`). 
 + 
 + 
 +==== 6.7.1 Short Runs (Start or Terminate Early) ==== 
 + 
 +Sometimes a service should start later or terminate earlier than the full route. 
 +This is useful for: 
 +  * depot in/out runs 
 +  * special services 
 +  * partial line operations 
 + 
 +Example: terminate at `TSD` (short turn / depot related movement):
  
 <code lua> <code lua>
 local TS_to_TSD = self.TestLine_Dir1:clone(0, nil, true):terminateAtStation("TSD", true); local TS_to_TSD = self.TestLine_Dir1:clone(0, nil, true):terminateAtStation("TSD", true);
 +
 table.insert(self.timetables, TS_to_TSD:clone(daytime(05, 10), DM.Weekdays)); table.insert(self.timetables, TS_to_TSD:clone(daytime(05, 10), DM.Weekdays));
 </code> </code>
  
-Start at `TSD`:+Example: start at `TSD` (depot insertion into service):
  
 <code lua> <code lua>
 local TSD_to_TSA = self.TestLine_Dir1:clone(0, nil, true):startAtStation("TSD", true); local TSD_to_TSA = self.TestLine_Dir1:clone(0, nil, true):startAtStation("TSD", true);
 +
 table.insert(self.timetables, TSD_to_TSA:clone(daytime(05, 20), DM.Weekdays)); table.insert(self.timetables, TSD_to_TSA:clone(daytime(05, 20), DM.Weekdays));
 </code> </code>
  
-==== 6.2 Platform Overrides ====+ 
 +==== 6.7.2 Platform Overrides (TestMap Example) ==== 
 + 
 +If you want to use the same template but spawn on a different platform, 
 +you can override platform numbers after cloning. 
 + 
 +Example: force first stop to use platform 1 instead of 2 at TS:
  
 <code lua> <code lua>
Line 186: Line 289:
 </code> </code>
  
-==== 6.3 Service Runs (Non-Passenger Moves) ====+This is useful if: 
 +  * multiple platforms exist 
 +  * you want different patterns at different times of day 
 +  * you temporarily reroute services during testing 
 + 
 +==== 6.7.3 Service Runs (Non-Passenger Moves) ==== 
 + 
 +A service run is a trip that should not be treated as a normal passenger service. 
 + 
 +Example: a depot-related move to TS marked as service run:
  
 <code lua> <code lua>
Line 197: Line 309:
 </code> </code>
  
-==== 6.4 Force Unique Stop Lists ====+==== 6.7.4 Force Unique Stop Lists (Safe Editing) ==== 
 + 
 +If you modify stop properties (platforms, PIS text, flags), 
 +it can be helpful to ensure the stop list is unique:
  
 <code lua> <code lua>
Line 203: Line 318:
 Variant:forceUniqueStopList(); Variant:forceUniqueStopList();
 </code> </code>
 +
 +This prevents accidental shared stop references when creating multiple variants.
  
 ---- ----
  
-===== Step — Depots and Dispatching =====+===== 7Depots and Dispatching ===== 
 + 
 +This section defines: 
 +  * depot storage spaces (optional) 
 +  * turnaround / dispatch behavior at stations 
 + 
 +==== 7.1 Depots (Parking Tracks / Depot Spaces) ==== 
 + 
 +Depots define **where AI trains are allowed to park** when they are not in service. 
 +They are also used by the ControlCenter for dispatching and (later) career mode. 
 + 
 +In the TestMap, the depot station is: 
 + 
 +  * `DP` (Depot) 
 + 
 +And it provides these depot tracks:
  
-Depots and dispatching strategies support the timetable traffic and keep trains moving.+  * 51, 52, 53, 54 (long depot tracks) 
 +  * 60 (short depot / test track)
  
-==== 7.1 Depots (Depot Spaces) ====+==== 7.1.1 Depot Table Structure ====
  
-`self.depots` groups depot tracks into named blocks.+`self.depots` is a table that groups depot tracks into named blocks (groups). 
 +Each group contains a list of `Depot_DepotSpace` entries.
  
 ^ Field ^ Meaning ^ ^ Field ^ Meaning ^
Line 218: Line 352:
 | platform | Track / platform ID as defined in the BP_StationDefinition | | platform | Track / platform ID as defined in the BP_StationDefinition |
 | direction | Which direction trains should park/spawn facing (1 or 2) | | direction | Which direction trains should park/spawn facing (1 or 2) |
-| noParkingTimetable | If true: no dedicated parking timetable is generated |+| noParkingTimetable | If true: no dedicated parking timetable should be generated for this track (useful to keep a track free) |
  
-Example:+==== 7.1.2 TestMap Example (DP 51–54 + 60) ====
  
 <code lua> <code lua>
Line 226: Line 360:
 self.depots = { self.depots = {
  
 + -- Main depot area (long tracks)
  ["DP_51_54"] = {  ["DP_51_54"] = {
  { station = self.stations.DP, platform = "51", direction = 2, noParkingTimetable = false },  { station = self.stations.DP, platform = "51", direction = 2, noParkingTimetable = false },
Line 233: Line 368:
  },  },
  
 + -- Short depot / test track (useful to keep free or for special moves)
  ["DP_60"] = {  ["DP_60"] = {
  { station = self.stations.DP, platform = "60", direction = 2, noParkingTimetable = true },  { station = self.stations.DP, platform = "60", direction = 2, noParkingTimetable = true },
Line 239: Line 375:
 </code> </code>
  
-----+Notes: 
 +  * The group keys (`"DP_51_54"`, `"DP_60"`) are just identifiers for readability. 
 +  * `platform` must match the platform numbers inside your **BP_StationDefinition** for DP. 
 +  * Use `noParkingTimetable = true` if you want to keep a track free (e.g. for turnarounds or testing).
  
-==== 7.2 Dispatching Strategies (Turnarounds / Depot Moves) ==== 
  
-Dispatching strategies define how trains are handled outside normal passenger services: +==== 7.2 Dispatching Strategies ====
-  * turnarounds at terminals +
-  * spawning trains from depots +
-  * sending trains back to depots +
-  * resolving conflicts / keeping traffic stable+
  
-Basic structure:+Dispatching Strategies define how trains are handled **outside of normal passenger service**. 
 +They are used to: 
 + 
 +  * turn trains around at terminal stations, 
 +  * spawn trains from depots, 
 +  * send trains back to depots, 
 +  * resolve platform conflicts, 
 +  * and keep traffic flowing when timetables alone are not sufficient. 
 + 
 +Dispatching is handled by the **ControlCenter** and works in addition to normal timetables. 
 + 
 +==== 7.2.1 Basic Structure ==== 
 + 
 +Dispatching strategies are defined as a table, grouped by station:
  
 <code lua> <code lua>
 ---@type table<Station, ControlCenter_DispatchingStrategy[]> ---@type table<Station, ControlCenter_DispatchingStrategy[]>
 self.dispatchingStrategies = { self.dispatchingStrategies = {
-    [self.stations.TS] = { +    [self.stations.WA] = { 
-        -- strategies for TS+        -- strategies for this station
     },     },
 } }
 </code> </code>
  
-Strategies are evaluated **top to bottom** (order matters).+Each station can have **multiple strategies**. 
 +They are evaluated **top to bottom**, so order matters.
  
----- 
  
-==== 7.2.Pattern A — Simple Turnaround ====+==== 7.2.2 When Dispatching Is Used ==== 
 + 
 +Dispatching strategies are evaluated when: 
 + 
 +  * a timetable ends at a station, 
 +  * a train needs to turn around, 
 +  * no suitable train is available for a departure, 
 +  * or a train must be moved to or from a depot. 
 + 
 +If no strategy matches, the train will remain idle. 
 + 
 + 
 +==== 7.2.3 Strategy Fields ==== 
 + 
 +Each dispatching strategy can define the following fields: 
 + 
 +^ Field ^ Description ^ 
 +| sourceStation | Station where the train currently is. Use `nil` for depot spawns. | 
 +| targetStation | Station the train should serve next. Use `nil` for depot despawn. | 
 +| sourcePlatforms | Allowed platforms the train may come from. | 
 +| targetPlatforms | Allowed platforms the train may go to. | 
 +| depotName | Name of the depot (as defined in the depots table). | 
 +| minLayover | Minimum minutes the train must wait before reuse. | 
 +| keepLine | Try to keep the train on the same line. | 
 +| replaceFirstPlatform | Replace the first stop platform if needed. | 
 +| replaceLastPlatform | Replace the last stop platform if needed. | 
 +| overrideFirstPlatform | Force a specific first platform. | 
 +| overrideLastPlatform | Force a specific last platform. | 
 +| timetable | Optional hidden timetable used for movements. | 
 + 
 +Not all fields are required for every strategy. 
 + 
 + 
 +==== 7.2.4 Pattern A — Simple Turnaround ==== 
 + 
 +This is the most common case:   
 +A train arrives at a station and turns around to serve the opposite direction. 
 + 
 +Example (Test Map):
  
 <code lua> <code lua>
 { {
- sourceStation = self.stations.TS+    sourceStation = self.stations.Kbo
- targetStation = self.stations.TS+    targetStation = self.stations.Kbo
- sourcePlatforms = { "1", "2" }, +    sourcePlatforms = { "1" }, 
- targetPlatforms = { "1", "2" }, +    targetPlatforms = { "2" }, 
- replaceFirstPlatform = true, +    minLayover = 3,
- keepLine = false, +
- minLayover = 4,+
 } }
 </code> </code>
  
-----+What happens:
  
-==== 7.2.2 Pattern B — Turnaround with Internal Movement ====+  * a train arriving on platform 1 
 +  * waits at least 3 minutes 
 +  * and departs again from platform 2
  
-Hidden timetables are used for internal shunting and must be service runs:+No depot is involved. 
 + 
 + 
 +==== 7.2.5 Pattern B — Turnaround with Internal Movement ==== 
 + 
 +Some stations require a **shunting move** to turn a train. 
 + 
 +In this case, a hidden timetable is attached:
  
 <code lua> <code lua>
 { {
- sourceStation = self.stations.Go, +    sourceStation = self.stations.Go, 
- targetStation = self.stations.Go, +    targetStation = self.stations.Go, 
- sourcePlatforms = { "1" }, +    sourcePlatforms = { "1" }, 
- targetPlatforms = { "2" }, +    targetPlatforms = { "2" }, 
- minLayover = 3, +    minLayover = 3, 
- timetable = Timetable:new("", 0) +    timetable = Timetable:new("", 0) 
- :setIsServiceRun(true) +        :setIsServiceRun(true) 
- :addStop({ +        :addStop({ 
- station = self.stations.Go, +            station = self.stations.Go, 
- platform = "6", +            platform = "6", 
- departure = 2, +            departure = 2, 
- turnAround = true, +            turnAround = true, 
- }) +        }) 
- :addStop({ +        :addStop({ 
- station = self.stations.Go, +            station = self.stations.Go, 
- platform = "2", +            platform = "2", 
- departure = 3, +            departure = 3, 
- }),+        }),
 } }
 </code> </code>
  
-----+This allows: 
 +  * temporary use of siding or crossover tracks 
 +  * clean turnarounds without blocking passenger platforms
  
-==== 7.2.Pattern C — Spawning Trains from a Depot ====+ 
 +==== 7.2.Pattern C — Spawning Trains from a Depot ==== 
 + 
 +When no train is available, dispatching can **fetch a train from a depot**. 
 + 
 +Example:
  
 <code lua> <code lua>
 { {
- sourceStation = nil, +    sourceStation = nil, 
- targetStation = self.stations.WA, +    targetStation = self.stations.WA, 
- targetPlatforms = { "1", "2" }, +    targetPlatforms = { "1", "2" }, 
- depotName = "WA_06_09", +    depotName = "WA_06_09", 
- overrideFirstPlatform = "3", +    overrideFirstPlatform = "3", 
- timetable = Timetable:new("", 0) +    timetable = Timetable:new("", 0) 
- :setIsServiceRun(true) +        :setIsServiceRun(true) 
- :addStop({ +        :addStop({ 
- station = self.stations.WA, +            station = self.stations.WA, 
- platform = "7", +            platform = "7", 
- departure = -5, +            departure = -5, 
- }) +        }) 
- :addStop({ +        :addStop({ 
- station = self.stations.WA, +            station = self.stations.WA, 
- platform = "3", +            platform = "3", 
- departure = -3, +            departure = -3, 
- }),+        }),
 } }
 </code> </code>
  
-`sourceStation = nil` means the train comes from a depot.+Key points:
  
-----+  * `sourceStation = nil` means the train comes from a depot 
 +  * the depot name must match the depots table 
 +  * negative departure times happen **before** the actual service
  
-==== 7.2.Pattern D — Sending Trains to a Depot ====+ 
 +==== 7.2.Pattern D — Sending Trains to a Depot ==== 
 + 
 +After service ends, trains can be removed from traffic. 
 + 
 +Example:
  
 <code lua> <code lua>
 { {
- sourceStation = self.stations.WA, +    sourceStation = self.stations.WA, 
- sourcePlatforms = { "1", "2" }, +    sourcePlatforms = { "1", "2" }, 
- targetStation = nil, +    targetStation = nil, 
- depotName = "WA_11_18", +    depotName = "WA_11_18", 
- timetable = Timetable:new("", 0) +    timetable = Timetable:new("", 0) 
- :setIsServiceRun(true) +        :setIsServiceRun(true) 
- :addStop({ +        :addStop({ 
- station = self.stations.WA, +            station = self.stations.WA, 
- platform = "3", +            platform = "3", 
- departure = 2, +            departure = 2, 
- }) +        }) 
- :addStop({ +        :addStop({ 
- station = self.stations.WA, +            station = self.stations.WA, 
- platform = "11", +            platform = "11", 
- departure = 6, +            departure = 6, 
- }),+        }),
 } }
 </code> </code>
  
-`targetStation = nil` means the train leaves traffic into a depot.+Here:
  
-----+  * the train leaves passenger service 
 +  * moves into the depot 
 +  * and is no longer available for dispatching
  
-==== 7.2.5 Hidden Timetables ==== 
  
-Hidden timetables:+==== 7.2.8 Hidden Timetables ==== 
 + 
 +Timetables inside dispatching strategies: 
   * are not shown to the player   * are not shown to the player
-  * should always use `setIsServiceRun(true)`+  * are always marked as `setIsServiceRun(true)`
   * are used only for internal movements   * are used only for internal movements
 +
 +They allow precise control over:
 +  * routing
 +  * speed limits
 +  * platform usage
 +  * turnarounds
 +
 +
 +==== 7.2.9 Strategy Order ====
 +
 +Dispatching strategies are evaluated **in order**.
 +
 +Recommended structure per station:
 +
 +  1. normal turnarounds
 +  2. depot spawn strategies
 +  3. depot despawn strategies
 +  4. fallback strategies
 +
 +This avoids unnecessary depot movements and keeps traffic stable.
 +
 +
 +==== 7.2.10 Common Pitfalls ====
 +
 +  * depot names not matching the depots table
 +  * missing `setIsServiceRun(true)` on hidden timetables
 +  * conflicting platform definitions
 +  * wrong strategy order
 +
 +If dispatching behaves unexpectedly, always check the order first.
 +
  
 ---- ----
  
-===== Common Pitfalls =====+===== 8) 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 
 + 
 +==== 8.1 Takeover Stations (Where the Player Can Start) ==== 
 + 
 +`self.cmTakeoverStations` is a list of stations where career mode allows a takeover. 
 + 
 +For the TestMap, we keep it simple: 
 + 
 +<code lua> 
 +-- Initializes data for career mode (optional) 
 +function TestMap:loadCareerMode() 
 + 
 + -- Stations where the player can take over in career mode 
 + self.cmTakeoverStations = { 
 + self.stations.TS,   -- TestStation (main terminus) 
 + self.stations.TSA,  -- TestStation Anfang (other terminus) 
 + self.stations.DP,   -- Depot (optional takeover) 
 + }; 
 + 
 +end 
 +</code> 
 + 
 +Notes: 
 +  * You reference the stations from `self.stations` (created in `loadStations()`). 
 +  * If a station is missing here, the player won’t be offered takeovers there. 
 + 
 +==== 8.2 Route Closures (Optional) ==== 
 + 
 +Route closures allow you to define sections that may be blocked in career mode. 
 +This is mainly for scenario systems and future gameplay logic. 
 + 
 +Each closure uses: 
 +  * `stationSource` → start of the closed section 
 +  * `stationTarget` → end of the closed section 
 +  * a DayMask (e.g. `DayMask.Always`, `DayMask.Weekdays`, `DayMask.Weekends`) 
 + 
 +Example for the TestMap (optional): 
 + 
 +<code lua> 
 +function TestMap:loadCareerMode() 
 + 
 + self.cmTakeoverStations = { 
 + self.stations.TS, 
 + self.stations.TSA, 
 + self.stations.DP, 
 + }; 
 + 
 + -- Optional: example closure between TS and TSA on weekends 
 + self.cmRouteClosures = { 
 +
 + stationSource      = self.stations.TS, 
 + stationTarget      = self.stations.TSA, 
 + tempClosure        = DayMask.Weekends, 
 + }, 
 + }; 
 + 
 +end 
 +</code> 
 + 
 +If you don’t need closures, simply omit `self.cmRouteClosures`. 
 + 
 +==== 8.3 cmGroups (Train Pool + Probability) ==== 
 + 
 +`self.cmGroups` defines which train compositions can appear in career mode. 
 + 
 +Each group represents a **probability set** for vehicle selection. 
 + 
 +You can define **multiple groups**. 
 +Each group has: 
 + 
 +^ Field ^ Meaning ^ 
 +| frequency | Probability factor in the range **0.0 – 1.0** | 
 +| compositions | List of composition `contentName` strings | 
 + 
 +Important: 
 +  * `frequency = 1.0` means **100 % chance** for this group to be considered. 
 +  * `frequency = 0.0` disables the group entirely. 
 +  * Values between 0.0 and 1.0 reduce the chance accordingly. 
 +  * The value is **not relative** to other groups. 
 + 
 +==== Example (TestMap) ==== 
 + 
 +<code lua> 
 +function TestMap:loadCareerMode() 
 + 
 + self.cmTakeoverStations = { 
 + self.stations.TS, 
 + self.stations.TSA, 
 + self.stations.DP, 
 + }; 
 + 
 + -- Career mode vehicle selection pool 
 + self.cmGroups = { 
 + -- Main vehicle pool (always available) 
 +
 + frequency = 1.0, 
 + compositions = { 
 + "Berlin_HK_2x", 
 + "Berlin_A3L92_4x", 
 + }, 
 + }, 
 + 
 + -- Optional / rare vehicles 
 +
 + frequency = 0.4, 
 + compositions = { 
 + "Berlin_HK_1x", 
 + "Berlin_A3L92_3x", 
 + }, 
 + }, 
 + }; 
 + 
 +end 
 +</code> 
 + 
 +Result: 
 +  * HK_2x and A3L92_4x are **always available** in career mode. 
 +  * HK_1x and A3L92_3x appear **only occasionally**, depending on the random selection. 
 + 
 +==== 8.4 Pathfinding Templates ==== 
 + 
 +Career mode also needs timetable templates that can be used for route finding. 
 + 
 +For the TestMap, we reference our two templates: 
 + 
 +<code lua> 
 +function TestMap:loadCareerMode() 
 + 
 + self.cmTakeoverStations = { 
 + self.stations.TS, 
 + self.stations.TSA, 
 + self.stations.DP, 
 + }; 
 + 
 + self.cmGroups = { 
 +
 + frequency = 1, 
 + compositions = { 
 + "Berlin_HK_2x", 
 + "Berlin_A3L92_4x", 
 + }, 
 + }, 
 + }; 
 + 
 + -- Templates that can be used for pathfinding 
 + self.pathfindingTemplates = { 
 + self.TestLine_Dir1, 
 + self.TestLine_Dir2, 
 + }; 
 + 
 +end 
 +</code> 
 + 
 +If you forget this, career mode may not be able to plan valid routes on your map. 
 + 
 +---- 
 + 
 +===== 9) Registering Stations and Timetables ===== 
 + 
 +The final step is registering runtime data with the ControlCenter: 
 + 
 +<code lua> 
 +controlCenter:setStationList(self.stations); 
 +controlCenter:setTimetableList(self.timetables, self.dispatchingStrategies, self.depots); 
 +</code> 
 + 
 +^ Call ^ Description ^ 
 +| setStationList | Registers all stations for routing, UI and spawning logic. | 
 +| setTimetableList | Registers AI services plus dispatching and depot logic. |
  
-  * station short names not matching BP_StationDefinition +If this function is missing or incomplete: 
-  * platform ids mismatching the BP_StationDefinition platform array +  * AI traffic will not work 
-  * compositions not registered or misspelled +  * stations may not be recognized for routing
-  * wrong dispatching strategy order +
-  * forgetting to insert cloned services into `self.timetables`+
  
 ---- ----
manual/subwaysim/map_construction/create_timetable.1769509209.txt.gz · Last modified: by dcs

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki