Auto Track Laying


Automatically lay track ghosts when walking or driving over them.

Content
3 years ago
1.0 - 1.1
6.25K
Trains

i Better than FARL

3 years ago

It's easy to use, better than farl. I hope the author can update the bio compatible wooden track

3 years ago

Hi! What is "bio compatible wooden track"?

3 years ago
3 years ago
(updated 3 years ago)

Just updated the mod to now place all entities that have "rail" in their name. That should support the new rails from bio industries, as well as any other mod that adds custom rails.

I hope it doesn't break other things, or doesn't add too many other entities as well now. Let me know if anything goes wrong on your end.

Have fun!

3 years ago

Nice going! You're very professional.

3 years ago

Hi! I just had a look at "Recently updated" and noticed your mod like a minute ago.

Just updated the mod to now place all entities that have "rail" in their name. That should support the new rails from bio industries, as well as any other mod that adds custom rails.

We'll see, I'll give it a try. As maintainer of BI, I've got a certain interest in this. :-D

I hope it doesn't break other things, or doesn't add too many other entities as well now. Let me know if anything goes wrong on your end.

Why don't you filter the entities by type -- "straight-rail" and "curved-rail"? Not every rail will have "rail" in its name, for example those from Cargo Ships:

{ type = "straight-rail",  name = "straight-water-way",  … },
{ type = "curved-rail",   name = "curved-water-way", … }
3 years ago

Why don't you filter the entities by type -- "straight-rail" and "curved-rail"? Not every rail will have "rail" in its name, for example those from Cargo Ships:

{ type = "straight-rail",  name = "straight-water-way",  … },
{ type = "curved-rail",   name = "curved-water-way", … }

Someone else also mentioned this. I wasn't aware that was a possibility, so definitely will change that.

The only two types I have to worry about are "straight-rail" and "curved-rail"? Or are there others too?

3 years ago

Ok, I now changed it to the following:

local ghost_types = {"straight-rail", "curved-rail", "rail-signal", "rail-chain-signal"}

local entities = player.surface.find_entities_filtered{
    position = position,
    radius = radius,
    ghost_type = ghost_types,
    type = "entity-ghost",
    collision_mask = "ghost-layer"
}

And then those entities will be build if you have enough resources like before.

Seems to work perfectly like this :D Thanks a lot!

3 years ago

The only two types I have to worry about are "straight-rail" and "curved-rail"? Or are there others too?

Don't confuse things! The vanilla rails are entities that have the same name as the prototype types:

data.raw["straight-rail"]["straight-rail"]
data.raw["curved-rail"]["curved-rail"]

All other rails -- whatever their name -- will be of one of these two prototype types. By the way, do you know the <CTRL>+<SHIFT>+<F> (default setting) feature? Hover the cursor on a building, rail, recipe or whatever and press those keys, then you can inspect all the settings for that prototype.

3 years ago

I did not know about ctrl+shift+f, very useful!

Thanks :D

3 years ago

Too fast for me! :-D

Ok, I now changed it to the following:

local ghost_types = {"straight-rail", "curved-rail", "rail-signal", "rail-chain-signal"}

Perhaps you should add "train-stop" to that list, they definitely belong to rails! And while we're at it, may I request a special feature for BI? It's a bit tricky, though.

BI has "powered rails". You can hook up a rail-to-power connector (basically a modified "medium-electric-pole") to a powered-rail track on one end, then you use powered rails all the way, hook up another rail-to-power connector -- and you've power at your outpost without placing power poles along your tracks. It would be nice if your mod would also place these. More on that later -- I'll try out your mod now!

3 years ago

"train-stop" is indeed a good one to add too. I'll do that later today. I'll also wait for the more information about rail-to-power :D

Thanks for testing!

3 years ago

I did not know about ctrl+shift+f, very useful!

Thanks :D

You're welcome! There's another very useful tool, by the way: Lua API global Variable Viewer (gvv). It won't help you much with this mod yet, but if your mod would store data in its global table, you could inspect its contents at runtime. CTRL+SHIFT+F gives you the static data on prototypes, gvv gives you access to runtime data, which may include the data of an individual entity.

3 years ago

I'll also wait for the more information about rail-to-power :D

Major bug found! Powered rails are combined entities. If a powered rail is placed, I put a hidden power pole on top of it (because rails can't transfer power in Factorio). This doesn't work with your mod because it just revives the ghosts secretly. As a rule of thumb, you should always raise an event if you build something, because you can never know what mods a player will use and if any of the mods will do something special with the things you build. Even entities based on prototypes you've defined yourself may be used and changed by other mods -- the only thing you can rely on is that there's nothing you can rely on. :-)

Luckily, this bug is easy to fix, just change line 21 to this:

success = entity.revive({raise_revive = true})

Then there's that one function that escaped into global scope (line 5). You should make it local!

local function sign(x)

While laying tracks, there was a rock blocking the track, another time there was a tree. Blocking entities should be returned by revive(opts), so you could use the return value to remove such things first and try placing the tracks again:

Return value
Any items the new real entity collided with or nil if the ghost could not be revived.
Note: If this is an entity ghost and it is successfully revived this will also return the revived entity or nil as a second return value and possibly item request proxy as the third parameter depending on value of return_item_request_proxy.

Support for the upgrade planner would also be nice. However, checking the surroundings for entity ghosts and entities marked for upgrade each time the player changes position may be a bit too expensive. So how about checking if the player is in a train before checking for upgradable tracks?

Checking player position may not be sufficient: Put down some track and place a locomotive with three wagons. Get into the last wagon. Place some ghost tracks ahead of the locomotive. The ghosts won't be revived because the player is too far away. In this case, it would be nice if items from the train would be used. But you only check if there are enough of the needed items in the player's inventory. I just emptied out my character completely and put everything in the first wagon behind the locomotive. The player (empty) was driving in the locomotive, but nothing was taken from the wagons, so the train was stuck.

Your code is very simple, which is good! I've got the latest version to run with Factorio 1.0 and 0.18 by just changing "factorio_version" and the dependency on "base". I'd recommend to make use of that asset -- continue to release for Factorio 1.0, or make that even 0.18! (Mods for 0.18 will work with 1.0, but a mod that requires Factorio 1.0 can't be loaded in 0.18.) I've been making double releases of BI for stable/experimental Factorio since 0.17/0.18, and since I released the first version for Factorio 1.1, the releases from the 0.18 branch always made up about 60% of the total downloads after some days. So releasing for old Factorio versions as well will definitely give your mod more exposure, for only very little additional effort.

Unfortunately, your mod is lacking a changelog. Please add one -- it's useful for yourself (keeping track of when you made what changes never hurts) and for your users (I always like to know what has changed before updating, so I can decide to delay the update if it causes problems with another mod etc.). If you do it right, it can even be displayed by the game's own mod manager. The parser is rather finicky, so trying it out before uploading is a good idea. Here is a changelog tutorial that explains everything in much detail.

Are you also TheOddler on the forum? I've played around with your control.lua yesterday and added some things already (raising the event; checking if a player is on a train and adjusting the position to that of the first locomotive/wagon in the direction the train is moving; made it easy to add prototype types/names from other mods). I could send you my version per PM -- feel free to use it as it is or just use it as an inspiration! :-)

3 years ago

Cool, thanks for the suggestions! I'll take a closer look at all of that after work.

But first about the last part, this mod is open source and tracked in git (that's kindof my version tracking :P). I'm happy to accept merge requests for any of these changes: https://gitlab.com/TheOddler/factorio-auto-track-laying

3 years ago

I'm very reluctant to use git -- never used it before for real, but I understand it's complicated, and I'd need to register. (I could probably learn to use git, but I'm really averse to registering anywhere. Made an exception for the forum and mod portal, but that's really an exception.) So, if you are available on the forum, I'd prefer to use that channel. :-)

3 years ago
3 years ago

OK. Just noticed that I made a stupid mistake, though. I'll send you the file when I'm really done. :-D

3 years ago

No worries :D Thanks for the effort!

3 years ago
(updated 3 years ago)

Took a bit longer than expected. Features:

  • Player can be just a character, or in a normal vehicle, or in any locomotive/wagon of a train (no need to be in the front loco/wagon).
  • When ghosts are revived, items are taken from the player first. If the player doesn't have any (or not enough) of the items needed, the vehicle will be checked for the missing items, and if the vehicle is part of a train (wagon or loco), items from the train (contents of all the wagons) will be used.
  • If rocks or trees are blocking the ghost, they will be mined. Mined items will be added to train contents (wagons) first, if there is not enough room, we'll try to put the items in the vehicle (if the player is riding in a locomotive, wood may be inserted into fuel slots), if there is still anything left, we'll try to give it to the player. If none or not all items could be inserted, the rest will be spilled on the ground and marked for deconstruction by the player's force.
  • Reviving ghosts will raise an event so that other mods can react.
  • Added a lot of code for prototype detection. At the start of the game, or when mods are added/removed/updated, the list of allowed prototype names will be rebuilt. Per default, that's just the rail stuff (rail tracks, signals, train stops). But there's also a compatibility list for different prototypes from other mods. For example, the "electric-pole" prototype will be added to the types list for Bio Industries' rail-to-power connectors or for Cargo Ships' floating poles if these mods are active. I don't know if anything else should be added for other mods, but if you get a request, just add the name of that mod, the prototype types, and a list of prototype names for those types (could be several names for the same type) to the list and everything else will be taken care of automatically. (This could be refined by adding a remote interface so that other mods can request or blacklist the prototypes they need/need to be ignored. But I didn't want to make it too complicated -- and I didn't want to rob you of all the fun mod development can be.)
  • Added support for the Lua API global Variable Viewer (gvv), which allows to inspect the global table of registered mods at runtime for easier debugging. (Just enter "/gvv" without the quotes on the game console to get the GUI!)

For future development, I'd suggest supporting not only ghosts, but also entities marked for upgrade and, perhaps, deconstruction. Shouldn't be too hard, you can reuse the list of prototype types/names used for filtering the ghosts. Just look for entities instead of ghosts, and add the to_be_deconstructed/to_be_upgraded flags to the filters …

I've sent you a PM with my version on the forum. It's a zip that could be uploaded almost as is (don't forget to turn off the log spamming in line 10 of common.lua!) because I had to have a running version for testing anyway. But of course, you are free to add, remove, or change anything you want -- it's your mod, after all, I just had some fun with it, and I'm glad I could learn a thing or two about trains and inventories. :-)

3 years ago

Awesome! I'll take a look at it today. Will come back to you.

3 years ago

Voila, went over the code, got confused, figured it out, cleaned it up a bit to my liking, and now released. Thanks a lot! I also added credits to you in the changelog for these changes.

3 years ago

Voila, went over the code, got confused,

Anything else would have been quite a surprise. I mean, even I've been confused by it more than once -- but I wrote this myself, so I knew exactly what I wanted the code to do and didn't have to figure that out the ways somebody else was thinking.

figured it out, cleaned it up a bit to my liking, and now released. Thanks a lot! I also added credits to you in the changelog for these changes.

Thanks for the credit! :-)

3 years ago
(updated 3 years ago)

Would you mind releasing an update where the hidden dependency on BI is removed? I'm almost done with the next BI release. It will include a migration script that adds the missing hidden poles to powered rails, but that doesn't make sense if players can still use old versions (<1.0.4) of your mod (any powered rails they'd place with that would be broken again). So I'll need to add a dependency on the latest version of your mod, but I can't do this as long as it depends on BI:

   3.744 Error ModManager.cpp:1514: Failed to load mod "Bio_Industries": Circular dependency from Bio_Industries to auto-track-laying

As it is now, I only have two options: Delay my update (which I can't do for too long because it is a bugfix release that also deals with some crashes), or add a conflict against ATL (which I wouldn't like to do because the mod seems so useful and the latest version actually is compatible with BI). A new version of ATL that changes just info.json should require minimal effort, but it would help me tremendously to get out of this mess, so I'd really appreciate it. :-)

3 years ago

Voila, new version released.

3 years ago

Thanks, I just confirmed that it works! BI 0.18.34 and 1.1.4 have an optional dependency "? auto-track-laying >= 1.0.5" now. Users of Factorio 1.0 won't be able to use your mod out of the box, but I'll add instructions how to get the latest version and make it compatible

3 years ago

Ah yes, I have to make a separate build for 1.0 too. I'll do that later. Not much time.

3 years ago

No problem, this should work for the time being. :-)

3 years ago

Just got a crash:

Error while running event auto-track-laying::on_player_changed_position (ID 82)
    LuaInventory API call when LuaInventory was invalid.
    stack traceback:
    __auto-track-laying__/control.lua:357: in function 'try_revive_entity'
    __auto-track-laying__/control.lua:516: in function <__auto-track-laying__/control.lua:450>

The inventory is created in line 349. Then there is the loop "for o, obstacle in ipairs(obstacles or {}) do" (lines 353…411). At the end of the loop (line 410), we call inventory.destroy(). So everything will work if there is only one obstacle. If there are more, the inventory won't exist any longer after the first obstacle has been cleared. So move inventory.destroy out of the loop (place it after instead of before "end") and everything will work fine.

One more issue (lines 333…339):

local obstacles = entity.surface.find_entities_filtered(
                          {
            position = entity.position,
            radius = 2,
            type = global.removable.filter.type,
            name = global.removable.filter.name
        })

While laying rails through a dense forest, the train would stop suddenly because there was an obstacle on the far end of a curved rail. Curved rails require four rails to build, so I increased the radius from 2 to 4 and after the trees that had been out of reach before were removed successfully, the train could move on.

3 years ago

I'll take a look at those tonight. Thanks for reporting :D

3 years ago

Fixes are live :D

3 years ago

Thanks! Turns out even 4 is not enough for the radius. I used /editor to spray trees (size: 60, intensity: 12) to create a very dense forest and laid some ghosts with loops and circles through it. At radius 4, there still were trees on the very edge of a curved track's ghost that could block placing the rail. But that's not enough to justify another update. (Offering a runtime-global setting for the radius may be an idea -- making that a runtime-user setting would be possible but is more complicated because you'd have to store and use the settings of each player.)

My last train stopped at a cliff, by the way. I knew I should have added that as well! :-)

Also, the mod is pretty much useless until rails have been researched. How about checking if the player's force already has researched the tech before checking the surface for ghosts? No need to run all the tests each time the player changes position when he can't place anything … But these are just ideas for the future, don't feel pressured!

3 years ago

I'll increase the radius in the code, so next time I do a full new release it'll be part of that.

Cliffs are a bit different, they need special items to remove. Could add that it searched for those as well, but idk, maybe in the future indeed.

New response