Content Patcher

Content Patcher

378k Downloads

[Automate] Overnight Pulls

IDMclean opened this issue · 7 comments

commented

I have not tested this extensively, but I do not believe I am getting the expected rate of production from Chest + Keg for the time elapsed while sleeping.

I am using 1000+ Coffee Beans which should produce Coffee roughly at a rate of 1 Coffee per Keg every 120 in game mins (2 in game Hours). Depending on how much I sleep, I expect to see 13 to 20 Coffee per Keg every day. When I stay up all day I see numbers approaching what I expect, but when I sleep through a day, I am getting much smaller numbers. Probably around 1-3 Coffee per Keg. Seems like the chests stop when you're asleep?

I haven't compared this to other possible configurations yet like with Furnaces, and Preserve Jars. I will update with test data shortly.

Update 1: Charcoal Kilns are confirmed to stop processing while you sleep. I place 800 wood in a chest with 1 Kiln attached and operating; this was done at 6:30AM game time, and I went to bed at 6:40AM game time. When I checked the chest on the following day around 6:10-6:20AM the 800 stack had only reduced to 790. A full day of processing is calculated in vanilla as 2400 minutes according to the wiki if you sleep the whole day through and 1600 minutes if you stay up to the point of passing out. That means that with continuous processing, I expect to see 530-800 wood consumed per day.

Update 2: testing with the Keg, Chrystalarium, and Charcoal Kiln indicates that the processors are pulling one load and processing it to completion during sleep, but the failure seems to be in additional pulls during sleep cycles.

Thanks for the mod and all y'alls other work.

commented

Closed as won't do. I'd certainly consider a pull request to do this if it worked well, but as it stands simulating overnight processing is outside the intended scope.

commented

@Pathoschild I appreciate your focus on the API. I am having thoughts about trying my hand at coding a fix for Automate, but it has been a long time since I wrote anything useful in any programming language, and I am not entirely familiar with Stardew Valley's engine or the SMAPI.

I think that exploring this issue might be helpful for further developing the SMAPI as it does not appear to have an easy handle for this condition in general? Seems like it would be a fairly basic feature we'd want for the SMAPI to handle time from when we sleep in game to the new day and to catch the condition/event that we are sleeping or falling asleep in the case of passing out.

I am curious about the difference between UpdateTick and the others; are they all equivalent in function or does UpdateTick have a particular tie with game state updates?
The machines continue to operate with slight inconsistency through your sleep cycle; do we know why and how this happens? Pardon if there is documentation for all this somewhere that I missed.

I might work a fix that yolks the pull requests to state changes of the machines during sleep cycle.

Thanks again for all your work, and thanks for your prompt reply.

commented

I've reviewed the Automate code and the SMAPI. I believe the issue exists in https://github.com/Pathoschild/StardewMods/blob/stable/Automate/AutomateMod.cs

Basically, it looks like there is an unhandled case having to do with the abrupt discontinuity of the simulation from sleep to new day. Outside of this condition, the relevant cases seem to be handled. But the "GameEvents.OneSecondTick += this.GameEvents_OneSecondTick;" does not trigger for the time between going to sleep & waking up?

From reading the SMAPI, it looks like there is a need to use some combination of TimeEvents, SaveEvents, MenuEvents, or UpdateTick?

commented

Hi @IDMclean. Yep, the problem is that time doesn't pass overnight. Automate would need some code on SaveEvents.BeforeSave to calculate how much time to simulate overnight, then fast-forward the machines. One complication is that the game may already have logic to account for time passing overnight, so we'd need to make sure Automate doesn't cause time to pass twice. That might be as simple as adding code in TimeEvents.AfterDayStarted to reset the machine to the point we calculated before save.

I'm mainly focusing on the SMAPI 2.0 migration for the next couple of months, so it might be a while until the next Automate release.

commented

@IDMclean Sorry for the less prompt reply this time. ;)

UpdateTick (and related events) are tied to the game state update. Game time doesn't actually pass at night; anything that seems to happen between bedtime and 6am is faked (e.g. in day-update methods). I haven't looked specifically into how machine processing is handled overnight, though.

Here's the modding documentation for reference, though it doesn't cover machine processing yet.

commented

I am playing around with mod making. I'm putting together a (hopefully) simple (to me) reflection mod that gives me a rough outline of the game's runtime state to specifically look at how sleeping and overnight production are handled. I'm aware there are decompilers I could use to peak under the hood, but I don't like decompilers and need the coding practice. If I get results (unlikely) prior to whatever you might be doing, I'll post em here.

My mod compiles and runs. Got it to the point that it outputs a file, but the reflection stuff is way different compared to Java which is what I am specifically familiar with. Java has a nice feature that allows you to produce XML representations of source code from runtime; it looks like C# doesn't have that exact functionality, & I'm going to need to experiment with your Helper and reflection interface for the game.

My sense about the machines is that there's probably some kind of event or state change we could listen for from the machines themselves to catch when they empty out at night. I'd expect we could make a kind of stopwatch based on there being stuff in the machine vs there not being stuff in the machine; depending on how the machines are telling time, check when player has "gone to sleep" and but before they have "woken up for the day" to see what state changes occur in the empty/not-emptiness of the machines then shove something in each time it empties in that condition. Would be less invasive (as another user put it) than simply coding an ad hoc time sim on top of whatever is going on.

Of course the setup could be very specific. Not sure how the machines would respond if they're not written to be refiled during the night. Or if they're simulated entirely on a single condition like immediately upon going to sleep or immediately upon waking up. Could be hairy.

Thanks for the tutorial on setting up MonoDevelop for SMAPI modding. It has been very helpful in all this.

Enjoy,
-Ian

commented

A bit speculative, but you would have to be pretty careful. Seems like the day update method will add the appropriate time to the all operating machines, but getting them to restart overnight would require making changes to what would likely be a complicated method - unless it's higher order enough that there is a submethod that could be overridden more succinctly.

I'm not totally up to date with the current state of the game, but additionally there were some inconsistency noted with how time passed for long term productions around the time sheds were introduced. If that bug is still around, it wouldn't surprise me if it originated with not being correctly implemented into the new day update method. You may want to do some initial testing just to make things are working predictably in vanilla, as unpredictable results after implementation might make later testing confounding.