(PC) Train World - railroad tycoon on a huge map

About me

My name is Dmytro, I am from Ukraine, and I've been a game developer for over 10 years. In the beginning, I worked on mobile games. Later I worked for the company focusing on interactive displays and various interactive solutions. For the past two years, I've been working on my own project Train World. I do enjoy transportation games a lot and always wanted to make one. I focused on one problem that always kept me frustrated - lack of space, and I addressed this in my game.

Idea

Train World has a large map. At the moment test map is over 38 000 square kilometers. Enough space to build the train network of your dreams. The other major aspect is the ability to operate trains that are 100 cars long.

Gameplay

The map is divided into regions. Each region has a capital some number of cities and industries. Build the railroad, connect industries and cities, and transport cargo and passengers. As soon as all the requirements are met you will be able to open more regions, discover new biomes/territories/cool places and expand your network.

There is no strict connection to the timeline. Play at your own pace. You start with trains of the mid-nineteenth century and progress via a tech tree. In the tech tree, you will be able to unlock more new trains and wagons.

There will be 3 eras. Each has its unique style which will be visible in the cities. You will be able to progress to the new era by reaching it in the tech tree.

Also, there will be a tasks system that will generate random tasks for you to complete and get nice bonuses.

Graphics and style

I would call this low poly with hi-res textures and a hint of cartoonish look. I have only two levels of LOD for trees on purpose. I believe this gives it a nice touch.

Status

The game has a page on Steam. The planned release is sometime in 2023.

Media

https://www.youtube.com/watch?v=9FBsqFgek-M

8530448--1138655--Screenshot_3.jpg
8530448--1138658--Screenshot_17.jpg
8530448--1138661--Screenshot_96.jpg
8530448--1138664--Screenshot_910.jpg

Work-in-progress test map.
8530448--1138652--Screenshot_0.jpg

Roadmap

The main focus at the moment is the Demo for steam. Features will be limited. You will be able to build rails, set up lines and trains, and deliver cargo and passengers. Only a couple of regions will be unlockable. The demo is planned for the end of this year or beginning of the next year.

Any feedback is welcome. Also, I plan to add a couple of tech posts about this game development. The were a number of challenges and I would like to share how I overcome them.

6 Likes

Trains? Wishlisted! :smile:

With a 195x195 km map size I do wonder how easy or tedious laying down tracks is. Bigger isn't always better. But I certainly like that the tracks so far (except for the third shot on the Steam page which seems a bit too tight) have very gentle, realistic curves.

[quote=“CodeSmile”, post:2, topic: 897871]
Trains? Wishlisted! :smile:

With a 195x195 km map size I do wonder how easy or tedious laying down tracks is. Bigger isn’t always better. But I certainly like that the tracks so far (except for the third shot on the Steam page which seems a bit too tight) have very gentle, realistic curves.
[/quote]

There were a number of challenges UX-wise. Only a part of the map is rendered at any given moment. That means only a small part of a track can be built. I have added a tool to the game that allows a player to make a guide in the map view and then lay track in the world view following the guide. Track laying is also fast, essentially you drag a mouse to a point where you want a track to be and hit a Space key on the keyboard. The next rail segment will start from where the previous one ended.

Because of the map size, I am using pretty much real-world dimensions for everything. And to mitigate any long waiting for a train to arrive at its destination, there is an 8X time scale available.

Packages that are used in the project and my comments on experience with these packages:

  • URP - has all the necessary features and is easy to work with
  • ShadreGraph - almost all shaders are done via shader graph, some of them are pretty complex, excellent tool
  • UI Toolkit - has a steep learning curve, but absolutely worth it. In the end, UI building becomes very easy and fast. UGUI is used only in a few very specific places.
  • Jobs and Burst - great tools, recommend mastering them for every Unity developer. Can dramatically improve performance in some cases. In my case, these packages are key for fast terrain generation and much more.
  • Entities and Hybrid Renderer - tough to start with. Without these packages, my game would not be possible. For example, at one moment there could be more than 200 000 trees rendered. Not easy to learn, complex, and demanding, but you will be generously awarded at the end of the learning cycle. For advanced developers only at this point, in my opinion.
  • Input System - nice tool, don't have a lot of experience with it. A lot of functionality and with it a bit more complicated than standard Input.

The rest of the packages are either dependencies or basic ones like Sprite2D or TextMeshPro.

Hey @Dimetrock
Thank you for bringing this DOTS project to our DOTS community as well.
I allow myself post the link for the reference.
https://discussions.unity.com/t/817846 page-3#post-8549918

I love trains as well :)
As you have already answered some of my questions above, I indeed look forward to more complex and interesting layouts.

Having very long trains can be very interesting, with many attached locos. Long hauling like the USA Amtrack, Santa FE etc.
But please don't underestimate small challenges, like stocking and joining wagons together on side tracks.
You can even make simple puzzle like game. Well, technically logistics.
Connect wagons in certain order, to deliver them into such and such place. And detach.
Adding challenges timer for loco maneuvers, could add fun playability, washout cratering new complex game mechanics.
It is fun to learn acceleration and deceleration of trains, with different sets and loads.
Arriving to the destination at x time, could bring some scoring. Let be optional. But let people feel some challenge as well, so they wont get bored.

Few things.
Can trains derail?
Can trains crash with each other?
Do you use any physics at all, or just simplistic 2D behavior?
Any tunnels planned?

Will be possible in future to do something like these?


See the time lapse at 10:40

@Antypodish

Trainyard operations, car sorting, etc., would be a game in itself. I thought about it, but these tasks are quite complex. Maybe, in the future, I will make a game about trainyards.

No physics in the game, I am afraid. Trains do move realistically, but there are no collisions.

There are tunnels and bridges in the game. Two tunnel types and five bridge types. Different tunnel and bridge types have different characteristics and sometimes even features.

1 Like

How I display rail tracks on the map

Problem: Display rail tracks on the map. Display selected lines.

What we have:

  • data on the tracks (geometry etc.), it also would be nice not to generate any additional data
  • rail tracks are dynamic (can be added or removed)
  • zoom friendly: from whole map overview to close-up zoom
  • 2D - map view is flat
  • rails are split into relatively short segments

My thought process. Rails are either lines or arcs and both could be represented via line or in our case a long rectangle. Since all of the rails will be viewed from up high it should look ok (and it does). This means that for each segment we create a rectangle of some width and length equal to the length of the segment.
8566196--1146452--PlanScheme.png
This can be done by making a quad mesh like the red rectangle above. Place it at the start and rotate it so that the far end matches the endpoint. One step is done.

Next, I didn't want to use thousands of MonoBehaviors in the scene representing my tracks on the map so I decided to use Entities. There are many other options available on how to display these rectangles like drawing meshes directly, batching them into one big one, or something else. I bet there are a lot of different solutions within Unity for this problem. This could be a great question for a job interview.

I stuck with Entities and this is a great tool for such kinds of problems. We are not bound by the amount pretty much, it is easy to create, destroy, and manage them. So now I have a bunch of rectangles on the map representing my rail tracks.

Now to the next part of the problem: Scaling. When we zoom in rails should get thinner and when we zoom out rails should get thicker. I decided to tackle this problem by modifying vertices in a shader. I went this path so I could keep a single mesh and a single material for all the rectangles. Yes, you read it right. All the rectangles are displayed via a single mesh and a single material. This is how I did it.

8566196--1146458--QuadNormals.png
In the mesh, normals (shown as blue arrows above) are representing the direction in which vertices(shown as green dots above) should scale. So in the shader a only need to calculate the scale value, multiply normal by this value, and set it to the vertex. 8566196--1146464--Shader.png
There are a couple of parameters for scale value calculation. In my case, it is based on the height of the camera. In the future, I will make it a property and set it from a script.

But this doesn't work. Since we decided to use one mesh for all segments we need to set the length of the mesh somehow. To do this we use entity scale. When we set the entity we set the z component of the scale to length. We also need to counter the scale on other vertices of complex shapes. I use rectangles with rounded ends.
8566196--1146473--Screenshot_1.png

Now our shader knows the scale of the mesh and scales the vertices correctly.

I put entities in a dictionary and change materials when I need to display a selected line.

I hope this post helps someone to solve their tasks or to be an inspiration for some new creations.

Recap

  • Use one mesh and one material
  • Write scale direction into normals in the mesh
  • Place mesh in the world at the start and point it towards the end
  • Scale rectangles Z axis to match length
  • Use scale and normals data in a shader to calculate and set new vertices positions.

This is how it looks in the game: 8566196--1146488--Screenshot_2.jpg

1 Like

Train World Demo is now available on Steam.

1 Like

Well done.
You may want to update your OP, with the indication of the Steam release.

Please do the same in DOTS forum, rather creating new reply there, as people will have difficulty to find that, among many various cool projects.
https://discussions.unity.com/t/817846 page-3#post-8549918

1 Like

As others have mentioned in other thread, the trailer with cars driving over people is so iconic :smile:

1 Like