NermNermNerm / Junimatic

MIT License
3 stars 7 forks source link

Junimos tend to Garden Pots #8

Open Jolly-Alpaca opened 4 months ago

Jolly-Alpaca commented 4 months ago

Any thoughts on allowing the junimos to tend to plants grown in Garden Pots? If this is already a thing, then nice! I'll just need to figure out what I did wrong (I put a tea plant in a pot by a junimo path, but the tea leaves were not automatically harvested). Vanilla Junimo Hut junimos don't harvest from Garden Pots, so this behavior wouldn't be overlapping with vanilla (not to mention the Junimo Hut can't be placed inside).

NermNermNerm commented 4 months ago

It's something that I've been thinking about quite a bit actually. Here are my thoughts so far:

  1. I'm not comfortable with Junimos doing anything more than picking multiple-harvest crops. There's another mod that pairs with Automate to allow the full spread - watering, planting, harvesting. To my taste, that feels too much like the mod playing the game for you.
  2. The main application I see right now is growing coffee and grapes. Coffee because right now growing and brewing your own coffee as a player takes way too much time. The grapes to make raisins, because long-term, I'd like to make it so that the Junimos work harder if they can snack on grapes.
  3. I'd love to have an indoor-sprinkler mod, but I haven't seen a mod that makes them sufficiently charming. I'd love to see one that was more interesting and artful than just the outdoor ones... I've got some ideas, but they involve a lot of graphics that I'm not really capable of making. (Or rather, not willing to spend the time necessary to develop the capability)
  4. As a compromise plan, I was thinking of allowing the player to somehow get around 5 boxes of Deluxe Retaining Soil. (Perhaps Pierre will send a mail to the player and then carry a very limited one-time stock of the stuff?)

It's my opinion that low-scale garden-pot gardening isn't something that many folks would be interested in if they had to do their own daily watering. I could be wrong.

I haven't acted on any of this yet because I think there are better ideas out there than what I've got so far. Maybe there should be a special "Junimo Garden Pot" that is Junimo-friendly, doesn't require watering and only grows certain crops. Maybe there should be a questline for it. Idunno.

Jolly-Alpaca commented 4 months ago

Only adding support for harvesting garden pots would be a good place to start, as that would just be extending what vanilla junimos already do.

Regarding watering, there are vanilla options. I've only really used garden pots for tea saplings, which do not require watering, or with the ultra retaining soil (or whatever the final tier is called) so the pot only ever needs to be watered once and never again (even after harvest). Of course the third tier of retaining soil is end game, but details :). I've also seen mods that add support to allow sprinklers to water garden pots. TLDR: There are alternatives to watering, so I wouldn't stress too much on adding that functionality, especially if you feel it would be game breaking/accessible before vanilla equivalents are.

Additional functionality could always be added as part of a future addition. For example, with the implementation of junimo snacks (grapes), perhaps the junimos might take up additional jobs (when bribed) or have job tiers they'll only do with "payment", such as watering crops/garden pots. The Better Junimos mod is an example of this kind of functionality. It enhances vanilla Junimos to perform additional tasks and it has configuration to require "payment" for the junimos to work as well as some kind of progression system. You could further limit watering functionality by requiring the player to provide a watering can with water for the junimo to use. Once the watering can is empty, the junimo won't water any more, so the player can't just walk away and come back to a chest full of crops one season later.

Jolly-Alpaca commented 4 months ago

TFW you expect something to be straightforward and it takes 4 hours just to track down how the vanilla code does it...

What are your opinions on Harmony patching? =D

NermNermNerm commented 4 months ago

I take a dim view of harmony patching. What do you think needs it? I don't think watering is that big a deal simply because retaining soil is already a thing. If I was to do something with watering, it would likely be in a mod dedicated to watering garden pots. Junimos don't have to be the answer to everything.

My notion was to give the player access to a very limited amount of endgame retaining soil just so they can access the junimos-harvest-pots feature in a timely fashion and not be hemmed in to either hassling with watering or being stuck just growing Tea.

Jolly-Alpaca commented 4 months ago

A few places in Crop.harvest to handle junimatic junimos; likely in all the same spots as where vanilla junimoHarvester is checked. The vanilla harvest logic could be replicated, but I like to defer to vanilla logic when possible so I don't have to account for all the conditions vanilla has already identified and handled. I'll admit I haven't gotten far enough to determine how the patch would be able to identify that junimatic is what is calling Crop.harvest. It's just an option.

So the harvest logic first needs to identify if it is harvesting a crop from dirt or from a bush (tea sapling or possible mod bushes). If harvesting from dirt, it needs to determine the crop, its quality, its quantity, and the effects things like profession, fertilizer, and luck have on those. It then needs to destroy the crop, if it is not a multi yield crop. Crop.harvest handles most of that (not the destroying bit, but returns true if the planted crop should be destroyed).

If harvesting from a bush, it needs to create the harvest item, then change the bush item to the harvested sprite texture and set the appropriate variables to indicate it has been harvested for the day. junimoHarvester.cs has logic for harvesting bushes that could be used as a base for what needs to be handled, but it does hardcode the produce as green tea leaves, which isn't ideal imo.

The resulting crop from these two paths (including the quality and quantity) would then be returned by TakeItemFromMachine to be handled by the junimatic framework as other objects are (I assume). If I'm not mistaken, the find work logic will need a small addition so junimatic finds pots with harvestable crops.

As a side observation, IndoorPot.CheckForAction (the method that handles harvesting when the player interacts with a pot) does check the base.heldObject.Value, but as far as I can tell, that is always null so I couldn't answer why it checks that.

Edit: I am now imaging junimos with tiny watering cans and dying inside.

NermNermNerm commented 4 months ago

Calling the base game code seems like it should be the idea, but often as not the base game code is smarmy as all hell and calling it is as much a crapshoot as rewriting it. You can also make some simplifications - like only harvesting multi-harvest crops. I'd also say it'd be fair if they always got base-quality items and no random multiple harvests, but from the sound of it you don't need to go there if Crop.harvest will do it for you. (But I worry that it might also want to award XP, which I'd rather it didn't).

For me, the image that's working on me is a Dr. Seussian contraption with a little hand in a white glove holding a watering can that pops out of a box erratically pouring water all around it.

Jolly-Alpaca commented 4 months ago

I can go either way on quality/quanity. I'd argue higher quality items and random multiple harvests are fair if this is functionality vanilla junimos already have, but you could argue that, on a fresh save, junimatic junimos are likely to be accessible before the vanilla junimo hut is and this may be enabling end game functionality too soon.

Then again, junimatic junimos will only work with garden pots, which have a lot of disadvantages to outdoors crops. Advantages

Disadvantages

Given all the disadvantages, is it fair to limit the possible quality of produce harvested by junimatic junimos, especially if quality fertilizer is used? The junimos are already slower than the farmer, which could be considered nerf enough.

The experience part is fair and can be handled. I don't think vanilla junimos reward experience either.

What type of junimo would handle garden pots? Forestry or crop?

Jolly-Alpaca commented 4 months ago
  1. Is gameMachine.heldObject strictly used for identifying machines ready for collection, with the actual object collected is handled by TakeItemFromMachine? I ask as it may be more efficient to only run the full harvest logic on collection and to load a dummy crop (the correct crop, but without quality and quantity) to flag the pot for harvest. I may have just thought of an alternative solution, but it would still be useful to know anyway (so I'm not writing hacky code/abusing certain functionality in unintended ways).
  2. If the machine returns multiple objects on output (fish pond is an example), do the junimos take the whole stack in one trip? I'm debating how to handle multi-yield per harvest crops like coffee. Should I push the full stack to the stack for collection or one at a time?
NermNermNerm commented 4 months ago
  1. Off-hand, I'd presume I was trying to ape what I expected StardewValley.Object.heldObject to do, which was be the thing that the machine produces (instead of most-of-the-time kindasorta doing that.)
  2. I think there are examples of that already where the machine produces more than one thing (although I don't know that I can think of it right now). So they should be able to pull the whole stack.

Also, I've been thinking about it some more. Maybe there's "logic" that says Junimos shouldn't water plants, but people don't download this mod because logic. They download it because the Junimos running around are just fun. Watering Junimos could be fun too - as long as there was some interesting animation to go along with it. I bet we could talk 6480 into making a well machine graphic...

Jolly-Alpaca commented 4 months ago

Apologies for the essay. I may just be writing my thoughts down for documentation/clarification purposes at this point. If you want to switch to another platform (e.g. discord) to discuss or throw your hands up in defeat, let me know. I'll try to stop with all the essays 👍. It's been an interesting deep dive.

Fish ponds can produce a stack (of roe and secondary items). Harvesting has the additional fun feature of having the potential for multiple distinct stacks of objects. For example, sunflowers return one sunflower and x number of sunflower seeds. Multi-yield harvest crops (e.g. coffee) return one of the crop with the rolled quality and the remaining x number of the crop at base quality (two separate stacks if the first crop isn't base quality). This means the junimatic junimo would need to make multiple trips to empty a garden pot, unless it can carry a list of items (I don't think it can carry more than one type of item at a time).

Question 1: How do Junimos handle output with multiple items of different types?

Good news is Garden Pot - Automate exists and makes a great reference on how to implement crop.harvest without needing to inject a bunch of custom code via a transpiler. It does not handle bushes though, as Automate natively supports that, and I'm not sure it handles foragables eithers. Maybe Automate also natively supports forageables, as forageables are added to the pot's heldObject field? Garden Pot - Automate also has some unique logic for spring onions, which are handled by crop.harvest, but spring onions don't have seeds in vanilla... May be something worth testing to see how necessary that logic is. (I'll skip the details on why I'm confused why it is necessary.) That spring onion logic is how it handles forageables.

Question 2: What object should be loading into the heldObject field to flag Junimatic to empty the garden pot?

Option A is hacky if heldObject is being used for more than just flagging the garden pot to be emptied. Option B seems less hacky, but is hacky for a whole host of other reasons.

Assuming Option B, my thought was to run the harvest logic as part of identifying what garden pots are ready for harvest. That way the quality, quantity, and full list of items is ready and the actual items can be pushed to heldObject. Then, when the junimo comes to collect, it can take what's in heldObject, as it does with other machines, and the next item in the list is moved to heldObject. The problem with harvesting it immediately, as opposed to when the junimo is at the pot, is twofold:

  1. Crop.harvest includes code for playing sounds. I imagine that'd be a bit odd to have a bunch of harvest sounds with no visible harvest.
  2. Only the junimo would be able to harvest the pot. (Note: the logic to destroy the crop/marking it as not ready for harvest is controlled by the method calling Crop.harvest, not by Crop.harvest itself.) If the logic to destroy the crop isn't called at the time the harvest logic is run and the junimo only looks at the heldObject, you could end up with duplicate harvests if the player manually harvests the garden pot before the junimo empties it. However, if you do destroy the crop at time of harvest logic, there is nothing for the player to harvest even if the junimo hasn't emptied the garden pot yet.
    • A possible solution is to not destroy the crop at harvest, but when the junimo takes the first item. This allows the player to manually harvest if they want without the potential for duplicates (for the most part; hilariously, vanilla junimos can softlock the game if the player harvests at the same time as the junimo). The junimo would check if the garden pot is still ready for harvest before taking the item and clear out the item variables/heldObject if it isn't. This doesn't fix number (1.) and the number of harvest stat handled in Crop.harvest has the potential to double count. There's also the possibility I haven't accounted for something and this wouldn't work anyway.

And then there are bushes. I'll stop here. Custom bushes exist making it a little more complicated to make sure that code runs, but theoretically it'll work?