How to Create Buslines and Bus Stops

This documentation gives the steps to create buslines. A busline is basically a route for the bus, which is composed of a number of bus stops.

CREATE FILES AND FOLDERS

  1. Create two new folders in the level you want to modify; name one “scenarios” and the other “buslines”. For example, if you are modifying the “smallgrid” level, create the folders in C:...\game\levels\smallgrid\

Note

If these folders already exist in the level you are modifying, skip this step.

  1. Inside the scenarios folder, create a new folder and name it “bus”. Inside the bus folder, you would need to create a bus_level.json file. To create these files, simply create a text document and save it with the desired name and extension (i.e. replace .txt with .json). The content of the files should be as follows:
[
    {
        "name": "bus_level",
        "description": "bus_level",
        "authors": "BeamNG",
        "introType": "none",
        "difficulty": "22",
        "date": 1494325025,
        "restrictToCampaign": false,
        "levelObjects": {
            "tod" : {
                "time" : 0.11,
                "dayLength" : 120,
                "play" : false
            }

        },
        "vehicles": {
            "scenario_player0": {
                "playerUsable": true,
                "startFocus": true
            },
            "*": {"playerUsable": false}
        },

        "radiusMultiplierAI": 2,
        "dialogs": {

            "scenario_objective_1":  [
                {
                    "type": "images",
                    "imgs": [
                        "scenarios/chapter_2/chapter_2_6_canyon.jpg"
                    ]
                }
            ]
        },
        "extensions": ["busdriver"],
        "busdriver": {
            "routeID": "1",
            "variance": "a"
        },
        "statistics":
        {
            "disableEndUI": true
        }
    }
]
  • Modify the first two variables, "name" and "description" by replacing the level part with the name of your level, for instance, use bus_utah.json if you are modifying the level “Utah”. Remember that this naming rule is not strict. In this example the “bus_grid.json” would be used for level smallgrid.
  • The "busdriver" object should contain the default route that the should be played, hence modify the "routeID" and "variance" accordingly.

Note

If the a json file for the bus scenario exists in the bus foler, skip this step.

  1. Create a simple text file in your buslines folder, with content similar to the template shown below. Save and name it levelName.buslines.json. Ensure that the .json filename is unique.
{
    "version": 1,
    "routes":[
        {"routeID":"1",
            "variance":"a",
            "direction":"Rexoni Diner",
            "routeColor": "#3b9c00",
            "vehicle" : {
                "model": "citybus",
                "config": "base"
            },
            "tasklist":[
                "tmpl_bs_07",
                "tmpl_bs_13",
                "tmpl_bs_02",
                "tmpl_bs_23",
                "tmpl_bs_26",
            ],
            "spawnLocation": {
                "pos": {"x": -613.572,"y": 199.223,"z": 113.173},
                "rotAngAxisF": {"x": 0,"y": 0,"z": 1,"w": 224.173}
            },
            "requiredWaypoints":{
                "wcu_bs_29":{
                    "wp":["wcu_cp_agave"],
                    "failmsg":"You got too far-off the route" },
                "wcu_bs_27":{
                    "wp":["wcu_cp_hwy"],
                    "failmsg":"You got too far-off the route" }
            },
            "navhelp":{
                "wcu_bs_13":["wpTown_16","Bridge36_3","Bridge36_1"],
                "wcu_bs_26":["bs_raceTrack_1","Bridge4_B1","Bridge4_A1","Bridge4_A2","countryside_road_1","countryside_road_2"],
                "wcu_bs_29":["Junction_mountain_A","Bridge1_B"],
                "wcu_bs_27":["countryside_road_3","Bridge2_A1","Bridge2_A2","Bridge2_A3","Bridge17_A","Bridge17_B","Bridge17_E"],
                "wcu_bs_28":["countryside_road_4"],
            },
            "previews":[
                "01_RexDiner.png"
            ]
        },
        {"routeID":"2",
            "variance":"a",
            "direction":"Khaki Bay",
            "routeColor": "#fff200",
            "tasklist":[
                "tmpl_bs_04",
                "tmpl_bs_01",
                "tmpl_bs_05_b",
                "tmpl_bs_14_b",
                "tmpl_bs_19_b",
                "tmpl_bs_25_b",
                "tmpl_bs_24_b",
                "tmpl_bs_27_b",
                "tmpl_bs_21",
                "tmpl_bs_17"
            ],
            "vehicle" : {
                "model": "citybus",
                "config": "base"
            },
            "spawnLocation": {
                "pos": {"x": -337.572,"y": 605.564,"z": 75.0979},
                "rotAngAxisF": {"x": 0,"y": 0,"z": 1,"w": 135.337}
            },
            "requiredWaypoints":{
                "wcu_bs_27":{
                    "wp":["wcu_cp_hrzn"],
                    "failmsg":"You got too far-off the route" }
            },
            "navhelp":{
                "wcu_bs_21":["Bridge17b_A"],
                "wcu_bs_17":["tennis_1","tennis_2"],
            },
            "previews":[
                "02_KhahkiBay.png"
            ]
        },
    ]
}

A few guidelines to creating your levelName.buslines.json document may come in handy at this point.

The .json file is made up of a json object that contains 2 variables: The “version” is a number that represents the version of buslines file. The “routes” is an array of json objects, with each object defining a bus route. Now each bus route object contains:

  1. "routesID" must be of string type, although it is actually a number e.g. "routeID":"101"
  2. "direction" ideally every route has two directions: one from A to B and another from B to A. This variable is used for display purposes. As a result, it is good to use naming conventions that can be easily recognized.
  3. "variance" is a string that describes a specific variant of the route. This is needed and used internally when a route ID has more than one variant.
  4. "routeColor" is a string representing route Color in html hexadecimal
  5. "vehicle" Keep your vehicle "model" as "citybus" and the "config" as "base"
  1. "tasklist" is a json array of strings (no space in between), which represents the triggers for your bus stops.
  2. "requiredWaypoints" is an optional json object that indicates compulsory points the vehicle must go through, and failure message if the vehicle does not go through them. Each element of the required way point object is also an object that contains 2 variables: an array containing the string-id of the way point that must be passed, and failure message that is displayed when the way point is not passed.
  3. "spawnLocation" is a json object containing 2 objects: "pos" and "rotAngAxisF", which represent the starting position and orientation of the vehicle. The rotation object could be either of two types:
    • "rot": a quaternion representation of rotation (given by LUA)
    • "rotAngAxisF": “angle and axis” representation of rotation used in the editor. The x, y, z denote the axis of rotation and w , the angle in degrees. This type is recommended because it’s easy to use.
  4. "navhelp" which is an optional json object that contains arrays named after the ids of the stops that require navigation help. These arrays contain waypoints (strings), through which the navigation arrow would pass.
  1. Rename and modify the variables and values in the levelName.buslines.json document, as desired and as directed in the previous step.
  2. Save the file.

CHOOSE YOUR SPAWN POINT

  1. Load the game and click Play>>Bus Routes>>Select Map. Then, select the map to be modified (where the new folders created). Choose a direction e.g. “Rexoni Diner”
  2. Press Shift+C to release the camera. Navigate through the map (using navigation keys A D W S) till you choose and reach the desired location for starting the trip. Try to move the view as close to the ground as possible.
  3. Press F11 to open editor mode.
  4. Click the Camera tab, and click Place Player at Camera. If your car is destroyed on landing, you can refresh by pressing the R key.
step9
  1. Click on the vehicle to display the vehicle marker. If the marker is not showing, go to the Scene Tree panel on the right side of the editor, and click Scene tab. Click the MissionGroup folder to open it, scroll down to the end to the ScenarioObjecsGroup folder. In this folder, select the scenario_player0, and this should select your vehicle and display its marker.
step10
  1. You can set your position and rotation by typing the values directly in the Transform tab of the Inspector panel to the right of the editor or by respectively using the Move Selection and Rotation Selection. For ease of manipulation, fix z = 0.35 for the position, and for rotation fix x = 0, y = 0, z = 1 in the Transform tab. You can then manipulate the x, y variables for position and the w value for your rotation.
../../_images/step11_move_selection.png ../../_images/step11_rot_selection.png
  1. Once you are satisfied with your desired starting position and orientation, copy these values from the Transform tab to “spawnLocation” in your levelName.buslines.json file.
  2. Save the file.

CREATE BUS STOPS

  1. In the Scene Tree panel, Scene tab, create a new folder under “MissionGroup”, by clicking the folder icon (in between the lock and delete icons).
step14

Name the new folder busstops and open the folder.

busstop_new
  1. In the game, press Shift+C to release the camera from the vehicle. Then, navigate through the map till you reach the desired location for your bus stop.
  2. In the Scene Tree panel, Library tab, Level tab, open the BeamNG folder
step16

and select LuaTrigger. This creates a trigger in the position of your camera.

  1. Modify the position, rotation and scale of the box trigger as described in step 11. In the scale of the trigger, make the “x” value accommodate the width of the vehicle and make the “y” value accommodate the length of the vehicle.

Note

since this trigger will be activated when the trigger box contains the vehicle, give the box dimensions, such that it is big enough to contain the vehicle. Also, it is advisable to let the bounding box, go a little below ground level. As a hint, try x = 4.5  y = 14.5  z = 7 for the scale of the bus trigger.

  1. When the desired size and location is achieved, go to the Inspector panel of the game editor. Copy the trigger identifier from your “tasklist” in the levelName.buslines.json file (e.g tmpl_bs_07) and paste it by the name option in the Inspector panel.
name_lua_trigger

Remember that this identifier must be a single string with no space within it, as indicated in step 3(f). Also, try to keep it short.

  1. Under the Trigger options, located under Transform, select “Box” “Contains” and “Bounding box” for TriggerType, TriggerMode and TriggerTestType, respectively. Set the “tickPeriod” to 1000 and enable the “ticking” option.
trigger_spec
  1. When this is done, scroll down the Inspector panel to Dynamic Fields.
busstop_dynfield
  1. Click the green + signnew entity. Doule click “dynamicField” and replace it with type, and replace “defaultValue” with busstop.
  2. Add another entity to the Dynamic Fields. Replace “dynamicField” with stopName, and replace “defaultValue” with the actual name of the bus stop, which would be displayed in the game, e.g. Fleet Street.
  3. Click File>>Save Level.
  4. Repeat steps 18 to 26 for each bus stop you want to create.
  5. In order to view the triggers you have created, release the camera with Shift+C, click the trigger you want to view in the busstops folder, and press the key F to place your camera at the trigger location. Make modifications, if necessary, and Save the level.