The most unhinged ways to transport items and yourself around your factory. Fling items around with Thrower Inserters, launch your trains off ramps, and soar through your base on electric ziplines! Updated for 2.0! Space Age special features being added gradually
Mods introducing new content into the game.
Transportation of the player, be it vehicles or teleporters.
Augmented or new ways of transporting materials - belts, inserters, pipes!
Trains are great, but what if they could do even more?
Sup, Drury here with another pipin' hot bug report for you
Some of you may have had the bright idea to jump your trains with Vehicle Wagon 2 in tow. On reflection, it was probably just me, but either way - can't be done.
https://mods.factorio.com/mod/VehicleWagon2
It either crashes when empty, or you lose your vehicle after the jump due to (I think?) a wagon ID mismatch.
So anyway, what do you guys think, do we have a case of harassing innocent mod developers on our hands or a reasonable bug report? I'll leave that up to you, so let me know in the comments.
Yep so that's all for now folks, take care, remember to subscribe and hit that like button and the bell seeya.
Hey Vsauce, Michael here..but who is Michael, and where is "here"?
To find out, we're going to be looking at the mod Vehicle Wagons 2 for Factorio. It allows you to basically store vehicles, like cars and tanks, on train wagons. Now while the vehicle is on the wagon, the vehicle itself is technically gone, snapped out of existence. And if you want to get the vehicle back, the information about the vehicle has to be written down somewhere for you to reference. As of right now, you unfortunately can't store that kind of information on the actual train wagon itself, so that's why Factorio gives each mod it's own database that it can use to write down information like that for later use.
But these databases are only accessible by the mod itself, and can't be seen by other mods. So if another mod wanted to, for example, temporarily delete the vehicle wagon so it can simulate the wagon flying through the air and then recreate it after it lands, it wouldn't have access to the information needed to know what vehicle goes onto the vehicle wagon it's trying to recreate. Some scientists have theorized using train IDs to keep the right links between mod databases and the actual train entity, but sadly Factorio doesn't yet allow mods to do this in it's API. The only option then would be for both mods to specifically program in some sort of compatibility with each other. Unlike our sponsor that will never require special compatibility patches: Raid Shadow Legends. Download for free today and show off your pro gamer moves.
And as always, thanks for watching
Hey there, I'm the maintainer for Vehicle Wagon 2. I'm open to adding an interface to access the "loaded vehicle" data. It's stored as a native Lua table based on the wagon "unit_number". (I already have an interface set up with Gizmo's Cark Keys to save and restore their metadata for vehicles that are loaded.) If you are interested in collaborating, we can work on it here or in forum DMs.
For starters, you could add support to Renai that adds the sprites and ignores the fact that they have metadata. The only consequence will be that when you try to unload it afterwards, it will simply not produce a vehicle. Then we can add the metadata transfer to re-register the new wagon with its cargo.
I've never made inter-mod compatibility change before, how does that work? I'm guessing the change would have to be in your mod's global variables like
global.LoadedVehicle[WagonUnitNumber] = Car
or something like that. I track the unit number of carriages before and after they jump, so I could easily say that the wagon with unit_number = A became wagon with unit_number = B. Does that work?
whops somehow posted twice by accident
I whipped up an interface real quick that I think will work. It's actually simpler for me to pass the LuaObjects themselves. So you would do something like this:
if remote.interfaces.VehicleWagon2.get_wagon_data then
global.savedVehicleWagons[thisWagon.unit_number] = remote.call("VehicleWagon2", "get_wagon_data", thisWagon) -- returns nil if not a vehicle wagon
end
-- delete thisWagon (remembering its unit number), fly through the air, create thatWagon
if remote.interfaces.VehicleWagon2.set_wagon_data then
remote.call("VehicleWagon2", "set_wagon_data", thisWagon, global.savedVehicleWagons[<thisWagons_unit_number>])
end
As for mod compatibility in general, sometimes it's important to put optional dependencies on mods whose remote interfaces you call during init. This makes sure they load and run before you try to interact with them. In this case, that's not a problem because you only ever need it while the game is running. The check to make sure the remote["blah"] table exists is there to see if the other mod exists, and if it has the right interfaces set up.
Edit: updated code to match the API I released.
Where would I add this in the code? Is this something i would place during the wagon recreation?
Yes, you would need to "get" the data before calling "destroy", and call "set" after calling "create_entity". So that the old or new wagon object is valid in each case.
Edit: I just uploaded a version of VehicleWagon2 with the interface included, so you can try it out! And updated the example code above so it will actually work.
Just tried it out and it works great. When the wagon jumps, it sends a message to chat that the wagon was destroyed, and when it lands, it says the wagon data couldn't be set. But when I go to take the vehicle back out with the winch it comes out just fine
Great! We can probably fix the error messages when I get a chance to look at it.
I'm not sure why the "data couldn't be set" message is appearing. Can you send me the test version of your mod? I'm robot256 on the forum, or a drive link works.
https://drive.google.com/file/d/1uPVMsXsCcB_zSnehEhlyq5EKMlozeJrc/view?usp=sharing
The implementation is in script\event\entity_damaged.lua line 293 for the vehicle storing before the wagon is deleted. Then in script\trains\on_tick.lua line 199 is where the wagon is recreated and vehicle is recalled
Awesome! To get rid of the log spam, I removed the message printed when the interface is called on a non-loaded-vehicle-wagon carriage. I also added another trick so that Vehicle Wagon knows not to freak out when a wagon is destroyed. Replace your "destroy()" call with two lines:
script.raise_event(defines.events.script_raised_destroy, {entity=event.cause, cloned=true})
event.cause.destroy({ raise_destroy = false })
This passes a custom parameter, "cloned", along with the script_raised_destroy event. If I see that parameter, I don't make any error messages because it means that particular vehicle lives on somewhere else. It's important that the event be raised just before actually destroying it, so that the entity is still valid while other mods handle the event.
The last detail is to figure out how to make Vehicle Wagon properly display the error message when a loaded wagon dies on impact. It looks like you recreate the wagon entity on impact just so you can destroy it, is that right? If you restore the vehicle wagon data at the same time, then VW would know to worry about it when it dies.
And then there is what to do with the sprites. The different types of wagons have some unusual sprite layers. Also need to test with the Aircraft and Big Truck mods because they unlock custom sprites too.
Essentially the jump works like this
I'm not too concerned about the sprite for now but it would definitely be nice to have it all work.
Okay, in that case you could generate the "Vehicle Lost" error message yourself when you create the wagon wreckage (and presumably delete the saved wagon data table). The following code is what generates this message in VW2, you can use the same thing (with the same locale strings). It checks to see if the stored vehicle still exists in the savegame, and names it accordingly.
if game.entity_prototypes[global.wagon_data[entity.unit_number].name] then
game.print{"vehicle-wagon2.wagon-destroyed", entity.unit_number, game.entity_prototypes[global.wagon_data[entity.unit_number].name].localised_name}
else
game.print{"vehicle-wagon2.wagon-destroyed", entity.unit_number, global.wagon_data[entity.unit_number].name}
end
Or I suppose we could add another interface function where you pass back the "destroyed" wagon data table.
Okay, I've added another interface function, "kill_wagon_data". It takes parameters "lost_data" (the stored wagon data) and "unit_number" (the number of the wagon that was destroyed, or leave it empty). Just call that before creating the debris and deleting the data.
Hey man sorry for the wait, I've been caught up in a lot of things recently. I haven't made any changes since the version I linked on google drive. Just need a quick refresher. You're saying if I insert remote.call("VehicleWagon2", "kill_wagon_data", WagonEntity, WagonEntity.unit_number) for wagons that land and explode, and also change the destroy() command for when a wagon just starts jumping with the two lines in your third above post, it should fix up the messages?
No problem! Yes, the two lines I posted to run when you "launch" a wagon and destroy it are correct. This will prevent VW2 from making extra error messages.
When a wagon crashes, use this code to generate the correct error message just before the explosion.
remote.call("VehicleWagon2", "kill_wagon_data", saved_wagon_data)
Essentially you are telling VW2 to kill the data instead of to restore it.
What goes into saved_wagon_data? Right now I am putting the data I get from using remote.call("VehicleWagon2", "get_wagon_data", event.cause) when the wagon jumps, but that gives me this error on train crashes
The message suppression on jump works though, I also got the jump sprite to work a bit better too
It should be event.cause.unit_number, or just leave out the last argument entirely.
So remote.call("VehicleWagon2", "kill_wagon_data", <saved_wagon_data.unit_number>) without a fourth input?
Oh, I misread your last post. Try
remote.call("VehicleWagon2", "kill_wagon_data", saved_wagon_data)
Where saved_wagon_data is exactly what you would otherwise pass as the last argument of set_wagon_data
That still causes the same crash unfortunately. I just uploaded a new version with the vehicle retention and jump message suppression, and left the remote call for kill_wagon_data in script\trains\on_tick.lua line 379 commented out. If it helps, you can try uncommenting it and launching a loaded vehicle wagon off a ramp to see what's going on
It was a stupid bug, fix uploaded now. Uncommenting those lines in your mod makes it work perfectly. It's awesome!
Sounds good, thanks for helping me out learn how to do mod compatibility 👌
My pleasure! Glad it worked out nicely.