Tracks

New Track definition format since 2023-05-26 route_prog_rework

Track node definition (NEW!)

Note: Advtrains supports rotating track nodes via param2, so defining one track node will define all 4 horizontal 90-degree rotations. Rotation is only supported along the vertical axis, param2 must always be within the range [0..3] (this is a restriction of the advtrains nodedb).

minetest.register_node(nodename, {
... usual node definition ...
groups = {
	advtrains_track = 1,
	advtrains_track_<tracktype>=1
	^- these groups tell that the node is a track
	not_blocking_trains=1,
	^- this group tells that the node should not block trains although it's walkable.
},

at_rail_y = 0,
^- Height of this rail node (the y position of a wagon that stands centered on this rail)
at_conns = {
	  [1] = { c=0..15, y=0..1 },
	  [2] = { c=0..15, y=0..1 },
	( [3] = { c=0..15, y=0..1 }, )
	( [4] = { c=0..15, y=0..1 }, )
	( ... )
}
^- Connections of this rail. There are two general cases:
   a) SIMPLE TRACK - the track has exactly 2 connections, and does not feature a turnout, crossing or other contraption
      For simple tracks, except for the at_conns table no further setup needs to be specified. A train entering on conn 1 will go out at conn 2 and vice versa.
	  A track with only one connection defined is not permitted.
   b) COMPOUND TRACK - the track has more than 2 connections
      This will be used for turnouts and crossings. Tracks with more than 2 conns MUST define 'at_conn_map'.
	  Switchable nodes, whose state can be changed (e.g. turnouts) SHOULD define a 'state_map' within the advtrains table.
	  This differs from the behavior up until 2.4.2, where the conn mapping was fixed.
^- Connection definition:
   - c is the direction of the connection (0-16). For the mapping to world directions see helpers.lua.
   - Connections will be auto-rotated with param2 of the node (horizontal, param2 values 0-3 only)
   - y is the height of the connection (rail will only connect when this matches)
^- The index of a connection inside the conns table (1, 2, 3, ...) is referred throughout advtrains code as 'connid'
^- IMPORTANT: For switchable nodes (any kind of turnout), it is crucial that for all of the node's variants the at_conns table stays the same. See below.
   
at_conn_map = {
	[1] = 2,
	[2] = 1,
	[3] = 1,
}
^- Connection map of this rail. It specifies when a train enters the track on connid X, on which connid it will leave
   This field MUST be specified when the number of connections in at_conns is greater than 2
   This field may, and obviously will, vary between nodes for switchable nodes.

can_dig=function(pos)
	return not advtrains.get_train_at_pos(pos)
end,
after_dig_node=function(pos)
	advtrains.ndb.update(pos)
end,
after_place_node=function(pos)
	advtrains.ndb.update(pos)
end,
^- the code in these 3 default minetest API functions is required for advtrains to work, however you can add your own code

advtrains = {
	on_train_enter=function(pos, train_id, train, index) end
	^- called when a train enters the rail
	on_train_leave=function(pos, train_id, train, index) end
	^- called when a train leaves the rail
	
	-- The following function is only in effect when interlocking is enabled:
	on_train_approach = function(pos, train_id, train, index, has_entered, lzbdata)
	^- called when a train is approaching this position, called exactly once for every path recalculation (which can happen at any time)
	^- This is called so that if the train would start braking now, it would come to halt about(wide approx) 5 nodes before the rail.
	^- has_entered: when true, the train is already standing on this node with its front tip, and the enter callback has already been called.
	   Possibly, some actions need not to be taken in this case. Only set if it's the very first node the train is standing on.
	^- lzbdata should be ignored and nothing should be assigned to it
	
	-- Fields of the "Passive Component API", which is used for any components that the interlocking system or LuaATC can switch.
	getstate = "string" -OR- function(pos, node)
	^- Provides (or, as a function, returns) the state string of this node. For a turnout, this is the direction the turnout is switched to.
	   Also non-track nodes can define this (or any of the other following fields) to define states that can be switched from interlocking or LuaATC.
	^- Conventions for this field are as follows:
	   - Two-way straight/turn switches: 'st'=straight branch, 'cr'=diverting/turn branch
	   - 3-way turnouts, Y-turnouts: 'l'=left branch, 's'=straight branch, 'r'=right branch
	   - Any node that can be turned on and off (e.g. Mesecon switches, Andrews Cross): 'on' and 'off'
	
	setstate = function(pos, node, newstate)
	^- Function to set the node into the specified state given by 'newstate'.
	   This may happen when interlocking sets a route, or when setstate() is called in LuaATC.
	   Most commonly, this will just swap the node at pos, but it can perform additional tasks.
	-- Be aware that above functions will be called even in unloaded areas. Always use the advtrains.ndb API to get and set nodes.
	
	
	state_map = {
		["st"] = { [1] = 2, [2] = 1, [3] = 1},
		["cr"] = { [1] = 3, [2] = 1, [3] = 1},
		["stateName"] = { ...conn_map table... },
	}
	^- The state map is required for the interlocking autorouter. For every possible state of the node that can be set with 'setstate',
	   the state_map contains the appropriate conn map. The following conditions must be satisfied for this system to work:
	   - The contents of the state_map for each state must be the same as the at_conn_map table of the node after calling setstate() on it
	   - The state_map, as well as the at_conns table, must be identical for all states of any given track.
}
})