Content Patcher

Content Patcher

378k Downloads

[Automate] Less invasive coding technique possible?

trak3r opened this issue ยท 3 comments

commented

I love the concept of this mod. It reminds me of my favorite original Tekkit mod in Minecraft.

However as I was perusing the code I noticed you are completely redefining the products of some machines.

For example, here you are defining the duration, profit, and naming of the jelly produced by the preserves jar:

https://github.com/Pathoschild/StardewMods/blob/stable/Automate/Machines/Objects/PreservesJarMachine.cs#L33

If the original game were to change the behavior of a preserves jar to produce faster, or be less profitable, or brand the product with the player's name, etc., this mod would essentially break that.

I'm wondering if there might be a less-invasive technique to exchange inventory between machines and chests (or pipes) without having to override the core logic of the machine? e.g. Introspection, Facades, Proxies, AOP, blah blah all the other OOP design patterns.

Thank you for your time and thank you for this mod.

commented

Hi @trak3r. We have limited options because machines aren't really object-oriented in the game. Most of their logic happens in a few giant methods with checks like if (this.name.Equals("Furnace")) ... else if (this.name.Equals("Keg")). That rules out most approaches we could take.

The main alternative is creating a fake farmer instance, manipulating its inventory, and making it interact with machines as if it was a player. That has a few drawbacks (e.g. you'll hear all the machine sounds), and limits what Automate can do.

In particular, Automate needs to peek at a machine's output without actually taking items. This lets us see what items are available for pushing into chests (if not full) and other machines (if they accept it as input). That isn't really something we could do with the fake-farmer approach; we'd need to take the items, try to push it into connected chests/machines, and if that fails un-take the items which would basically involve redefining the logic anyway.

So in the end redefining the machine logic is the only approach I found that works for what Automate is intended to do. The code is open-source and each machine has a link to the original code it's based on, which is intended to make it easier to update for future game changes.

If you do think of a good way to implement Automate without redefining the machine logic, let me know! :)

commented

machines aren't really object-oriented in the game. Most of their logic happens in a few giant methods

That's most unfortunate. Thank you for the explanation.

each machine has a link to the original code

I'm not able to find that. Could you please explain further? I would love to see the original code as well. Perhaps I could then recommend some non-invasive alternatives.

If you do think of a good way to implement Automate without redefining the machine logic, let me know!

I absolutely will try.

commented

You can decompile the game to see how the machines are implemented. It's a bit messy, but you'll find most of the logic in Object::checkForAction and Object::performObjectDropInAction for most of the machines. Some machines have logic elsewhere (like Cask::performObjectDropInAction). It looks like I forgot to document where the original code for each machine is, but I'll put that in for a future update.