Transport Fever 2

Transport Fever 2

Create your own game world!
Give your game a personal touch and change it to your liking. Create, share and install mods. Customize the game with new landscapes, vehicles, stations, assets and more.
How to use type.NodeId or type.EdgeId?
Hey all, I've been staring at this forever and still can't figure it out. The api has a bunch of commands available for stations:
https://transportfever2.com/wiki/api-testing/modules/api.engine.html#Station_System

For example:
api.engine.system.stationSystem.getPersonNodeId2StationTerminalsMap( WHAT GOES HERE?? )

but I can't figure out from the api docs what goes in the ( ). The doc says:

getPersonNodeId2StationTerminalsMap()
Gets all transport network nodes associated with a station terminal.
Returns:

{[type.NodeId] = {{Entity,int},...},...}

Clicking on type.NodeId takes me to this:

NodeId
References a single transport network node within a transport network entity
Fields:

new func constructor, either no parameters or and entity and an index
entity Entity the type.ComponentType.TRANSPORT_NETWORK entity
index int the index within the edges field of the transport network component (starting at 0)

and I feel like I'm going in circles...

In the console I've used api.type.getComponent( entity ID# of a station, 59) to get the data for a specific station. At the bottom it shows the vehicleNodeID, for example:
vehicleNodeId = {
new = nil,
entity = 33992,
index = 0,
},

But when I put that entity # 33992 in the "WHAT GOES HERE??" above it just gives an error because my syntax is wrong.

What's the syntax for this function?


Edit: Context... I'm debugging a mod and trying to use console commands to see what person nodes / edges are connected to a vehicle node in a station.
Last edited by RadiKyle; 14 Jan @ 5:59pm
< >
Showing 1-9 of 9 comments
This one doesn't actually take any parameters at all and returns a map:

>> api.engine.system.stationSystem.getPersonNodeId2StationTerminalsMap() { [{ new = nil, entity = 194703, index = 191, }] = { [1] = 194820, }, [{ new = nil, entity = 160987, index = 372, }] = { [1] = 170139, },

which is a bit confusing as the key is actually a hash/dictionary that points to an array/list
Ugh I messed up my copy/paste and got the wrong functions... 🤦‍♂️ Although this one was very helpful too because I also tried that one earlier.

The ones I meant to ask about are:
getStationTerminalForVehicleNode(nodeId)
getStationTerminalsForPersonEdge(edgeId)
getStationTerminalsForPersonNode(nodeId)

Edit: They all have similar ref info to this:
Parameters:

nodeId type.NodeId the vehicle node id that is queried for

Returns:

{Entity,int}
Last edited by RadiKyle; 14 Jan @ 7:35pm
I struggled with this as well, here's my train of thought:

api.engine.system.stationSystem.getVehicleNodeId2StationTerminalsMap() { [{ new = nil, entity = 7566, index = 0, }] = 6707,


6707 is a station:
>> api.engine.getComponent(6707, 63) { name = "Upper Melton Mowbray", }

So, I'm looking at entity 7566, to figure out what that might be (in the debug window):



>> for i=1,100 do a=api.engine.getComponent(7566, i) if a then print (i) print(a) end end 8 userdata: 0x60001a6a42f8 24 userdata: 0x60001a6a6828 52 userdata: 0x600006cfaa28 56 userdata: 0x60001a63dd38

Going back to your original question, I figured out so far:

getStationTerminalForVehicleNode(nodeId) the nodeId needs to be userdata, so it can be made with:
>> api.type.NodeId.new(6503,0) { new = nil, entity = 6503, index = 0, } >> api.engine.system.stationSystem.getStationTerminalForVehicleNode(api.type.NodeId.new(6503,0)) 6547 >

(6547 is a station entity)

The EdgeId works in a similar fashion:
>> api.type.EdgeId.new(2345,0) { new = nil, entity = 2345, index = 0, }

One thing to remember here, that despite the way the debug window presents these values they are NOT Lua tables, but userdata. Which means that some things (like iterators) don't always behave the way you'd expect. One very important thing to remember is to never directly refer to the sub-fields of the returned userdata like this:
local value = api.engine.getComponent(7566, 52).nodes[1]

but instead use this:
local apiResponse = api.engine.getComponent(7566, 52) local value = apiResponse.nodes[1]

The first notation can result in random crashes when the underlying userdata object gets garbage-collected (on the game side) but the Lua library has no way of determining this.
Last edited by peteraklnz; 14 Jan @ 11:37pm
Ok I think I'm extra lost now lol 🙈 Lost me at the 6503 number / type..new stuff. I don't get where it comes from, or why create a new node.

Instead of print(a) I can use debugPrint(a) to expand the userdata stuff. (Seems to do the same thing as print(table.toString(a)), except the latter doesn't seem to work in this context.)

But I don't want to examine it anyhow because I already know what the entity is -- it's a vehicleNode, personNode, or personEdge that I get from the station info, like this:
vehicleNodeId = { new = nil, entity = 33681, index = 0, },
I'm simply trying to use it as the input in one of those getStationTerminalFor- functions above, to reverse-trace the link between them and the station terminals.

So for
getStationTerminalForVehicleNode(nodeId)
the ref doc says: "nodeId" is "type.NodeId", suggesting I need something like this:
getStationTerminalForVehicleNode(type.NodeId)
But what do I type for "type.NodeId"?? 🤷‍♂️ If I just use this:
getStationTerminalForVehicleNode(33681)
it gives an error.
This is were the fun begins. Those 'map' functions (like api.engine.system.stationSystem.getVehicleNodeId2StationTerminalsMap()) are a good starting point as they give you a lot of data that you might be able to reverse-engineer into something useful. I generally look for things like station ids (and station group ids), town ids and train ids. Once I have those I try to figure out what the other relations might be.

On that particular function to "create" a new nodeId - you're not really creating anything - that nodeId is existing (taken from the map before, I just trimmed too much of the output). You're building a lua 'userdata' object here that can be passed as a parameter to the api.engine.system.stationSystem.getStationTerminalForVehicleNode() function.

so there are two steps here: build the userdata object and provide it to the API call to get the data back:
local myNodeId = api.type.NodeId.new(6503,0) local myTerminal = api.engine.system.stationSystem.getStationTerminalForVehicleNode(myNodeId)

It takes a bit of experimentation and guessing to figure out what links to what and how.
RadiKyle 6 15 Jan @ 11:33am 
Ok so it's basically making a copy/reference link of the existing node that can be used in the function's context? Ok I think I can grasp that (maybe, lol).

So I tried it but the results weren't very helpful. In my station entity 33711, terminal [1] has vehicleNode 33681. So I made the type.new "copy" of 33681, and then stuffed it into the getStationTerminalForVehicleNode function. The result was 33711 (plus a nil if I table/debug print), which is the station entity, but no terminal number. The ref doc suggests the function is supposed to return the terminal number, so still seem to be missing something if the function is supposed to live up to its label 🤔

Edit: the console...
>> myNodeId = api.type.NodeId.new(33681,0) myTerminal = api.engine.system.stationSystem.getStationTerminalForVehicleNode(myNodeId) >> myNodeId { new = nil, entity = 33681, index = 0, } >> myTerminal 33711 >> print(table.toString(myTerminal)) 33711 nil >> debugPrint(myTerminal) 33711 nil
Last edited by RadiKyle; 15 Jan @ 11:35am
RadiKyle 6 15 Jan @ 12:24pm 
...It's also not working for the personEdge case... It returns [1] = 33711 but the input edge I used is [6].

Emailed UG for some guidance...

Edit: I mean we shouldn't have to guess how to use it, so it seems to be a "hole" in the ref doc.

Many thanks for the help, learned a bunch today! 🙏

Last edited by RadiKyle; 15 Jan @ 12:30pm
If you're looking to find a simple sequential number here (that denotes the number of terminal) you'll most likely have to dig through a number of other objects first. I suspect the terminal sequence number is nothing more than a list index somewhere.
The station table already has all the info. Running api.engine.getComponent(37415,59) for example produces this: https://pastebin.com/yNjsnN4S
For every terminal in the station it lists every personNode, personEdge, and vehicleNode. So the 3 getStationTerminalFor- functions are simply doing the lookup in the other direction. At least that's what the API ref indicates.
< >
Showing 1-9 of 9 comments
Per page: 1530 50