Renai Transportation


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

Content
59 minutes ago
0.18 - 2.0
38.0K
Transportation Logistics Trains

g Vehicle Wagon crash [Compatibility added✅]

3 years ago

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.

3 years ago
(updated 3 years ago)

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

3 years ago

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.

3 years ago

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?

3 years ago
(updated 3 years ago)

whops somehow posted twice by accident

3 years ago
(updated 3 years ago)

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.

3 years ago

Where would I add this in the code? Is this something i would place during the wagon recreation?

3 years ago
(updated 3 years ago)

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.

3 years ago

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

3 years ago

Great! We can probably fix the error messages when I get a chance to look at it.

3 years ago

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.

3 years ago

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

3 years ago
(updated 3 years ago)

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.

3 years ago

Essentially the jump works like this

  • Detect collision with ramp
  • Store everything about the wagon
  • Destroy the wagon
  • Animate the sprite jumping
  • After its calculated air time, try to create a wagon of the same name at the landing position
  • If one was successfully created, restore all its properties
  • If one was not created (there's no rail at the landing zone/the rail is occupied) create an explosion and damage things in the area. In this case the wagon entity is not recreated
  • If one was successfully created but the rail it is created on is perpendicular to the way it jumped, then the created wagon is destroyed and an explosion is created.
  • Other stuff handling train landing but at this point the wagon entity either exists, was destroyed, or was never created.

I'm not too concerned about the sprite for now but it would definitely be nice to have it all work.

3 years ago

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.

3 years ago

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.

3 years ago

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?

3 years ago

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.

3 years ago
(updated 3 years ago)

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

3 years ago

It should be event.cause.unit_number, or just leave out the last argument entirely.

3 years ago
(updated 3 years ago)

So remote.call("VehicleWagon2", "kill_wagon_data", <saved_wagon_data.unit_number>) without a fourth input?

3 years ago

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

3 years ago

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

3 years ago

It was a stupid bug, fix uploaded now. Uncommenting those lines in your mod makes it work perfectly. It's awesome!

3 years ago

Sounds good, thanks for helping me out learn how to do mod compatibility 👌

3 years ago

My pleasure! Glad it worked out nicely.

New response