| 
									
										
										
											
												Stardew Valley 6.x.x: The Content Update (#3478)
Focus of the Update: Compatibility with Stardew Valley 1.6 Released on March 19th 2024
This includes randomization for pretty much all of the new content, including but not limited to
- Raccoon Bundles
- Booksanity
- Skill Masteries
- New Recipes, Craftables, Fish, Maps, Farm Type, Festivals and Quests
This also includes a significant reorganisation of the code into "Content Packs", to allow for easier modularity of various game mechanics between the settings and the supported mods. This improves maintainability quite a bit.
In addition to that, a few **very** requested new features have been introduced, although they weren't the focus of this update
- Walnutsanity
- Player Buffs
- More customizability in settings, such as shorter special orders, ER without farmhouse
- New Remixed Bundles
											
										 
											2024-07-07 16:04:25 +03:00
										 |  |  | from __future__ import annotations | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-27 03:28:00 +01:00
										 |  |  | from graphlib import TopologicalSorter | 
					
						
							| 
									
										
										
											
												Stardew Valley 6.x.x: The Content Update (#3478)
Focus of the Update: Compatibility with Stardew Valley 1.6 Released on March 19th 2024
This includes randomization for pretty much all of the new content, including but not limited to
- Raccoon Bundles
- Booksanity
- Skill Masteries
- New Recipes, Craftables, Fish, Maps, Farm Type, Festivals and Quests
This also includes a significant reorganisation of the code into "Content Packs", to allow for easier modularity of various game mechanics between the settings and the supported mods. This improves maintainability quite a bit.
In addition to that, a few **very** requested new features have been introduced, although they weren't the focus of this update
- Walnutsanity
- Player Buffs
- More customizability in settings, such as shorter special orders, ER without farmhouse
- New Remixed Bundles
											
										 
											2024-07-07 16:04:25 +03:00
										 |  |  | from typing import Iterable, Mapping, Callable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .game_content import StardewContent, ContentPack, StardewFeatures | 
					
						
							|  |  |  | from .vanilla.base import base_game as base_game_content_pack | 
					
						
							| 
									
										
										
										
											2025-04-08 12:37:45 -04:00
										 |  |  | from ..data.game_item import GameItem, Source | 
					
						
							| 
									
										
										
											
												Stardew Valley 6.x.x: The Content Update (#3478)
Focus of the Update: Compatibility with Stardew Valley 1.6 Released on March 19th 2024
This includes randomization for pretty much all of the new content, including but not limited to
- Raccoon Bundles
- Booksanity
- Skill Masteries
- New Recipes, Craftables, Fish, Maps, Farm Type, Festivals and Quests
This also includes a significant reorganisation of the code into "Content Packs", to allow for easier modularity of various game mechanics between the settings and the supported mods. This improves maintainability quite a bit.
In addition to that, a few **very** requested new features have been introduced, although they weren't the focus of this update
- Walnutsanity
- Player Buffs
- More customizability in settings, such as shorter special orders, ER without farmhouse
- New Remixed Bundles
											
										 
											2024-07-07 16:04:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def unpack_content(features: StardewFeatures, packs: Iterable[ContentPack]) -> StardewContent: | 
					
						
							|  |  |  |     # Base game is always registered first. | 
					
						
							|  |  |  |     content = StardewContent(features) | 
					
						
							|  |  |  |     packs_to_finalize = [base_game_content_pack] | 
					
						
							|  |  |  |     register_pack(content, base_game_content_pack) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Content packs are added in order based on their dependencies | 
					
						
							|  |  |  |     sorter = TopologicalSorter() | 
					
						
							|  |  |  |     packs_by_name = {p.name: p for p in packs} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Build the dependency graph | 
					
						
							|  |  |  |     for name, pack in packs_by_name.items(): | 
					
						
							|  |  |  |         sorter.add(name, | 
					
						
							|  |  |  |                    *pack.dependencies, | 
					
						
							|  |  |  |                    *(wd for wd in pack.weak_dependencies if wd in packs_by_name)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Graph is traversed in BFS | 
					
						
							|  |  |  |     sorter.prepare() | 
					
						
							|  |  |  |     while sorter.is_active(): | 
					
						
							|  |  |  |         # Packs get shuffled in TopologicalSorter, most likely due to hash seeding. | 
					
						
							|  |  |  |         for pack_name in sorted(sorter.get_ready()): | 
					
						
							|  |  |  |             pack = packs_by_name[pack_name] | 
					
						
							|  |  |  |             register_pack(content, pack) | 
					
						
							|  |  |  |             sorter.done(pack_name) | 
					
						
							|  |  |  |             packs_to_finalize.append(pack) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     prune_inaccessible_items(content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for pack in packs_to_finalize: | 
					
						
							|  |  |  |         pack.finalize_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Maybe items without source should be removed at some point | 
					
						
							|  |  |  |     return content | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def register_pack(content: StardewContent, pack: ContentPack): | 
					
						
							|  |  |  |     # register regions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # register entrances | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     register_sources_and_call_hook(content, pack.harvest_sources, pack.harvest_source_hook) | 
					
						
							|  |  |  |     register_sources_and_call_hook(content, pack.shop_sources, pack.shop_source_hook) | 
					
						
							|  |  |  |     register_sources_and_call_hook(content, pack.crafting_sources, pack.crafting_hook) | 
					
						
							|  |  |  |     register_sources_and_call_hook(content, pack.artisan_good_sources, pack.artisan_good_hook) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for fish in pack.fishes: | 
					
						
							|  |  |  |         content.fishes[fish.name] = fish | 
					
						
							|  |  |  |     pack.fish_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for villager in pack.villagers: | 
					
						
							|  |  |  |         content.villagers[villager.name] = villager | 
					
						
							|  |  |  |     pack.villager_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-08 12:37:45 -04:00
										 |  |  |     for building in pack.farm_buildings: | 
					
						
							|  |  |  |         content.farm_buildings[building.name] = building | 
					
						
							|  |  |  |     pack.farm_building_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-20 10:17:22 -04:00
										 |  |  |     for animal in pack.animals: | 
					
						
							|  |  |  |         content.animals[animal.name] = animal | 
					
						
							|  |  |  |     pack.animal_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Stardew Valley 6.x.x: The Content Update (#3478)
Focus of the Update: Compatibility with Stardew Valley 1.6 Released on March 19th 2024
This includes randomization for pretty much all of the new content, including but not limited to
- Raccoon Bundles
- Booksanity
- Skill Masteries
- New Recipes, Craftables, Fish, Maps, Farm Type, Festivals and Quests
This also includes a significant reorganisation of the code into "Content Packs", to allow for easier modularity of various game mechanics between the settings and the supported mods. This improves maintainability quite a bit.
In addition to that, a few **very** requested new features have been introduced, although they weren't the focus of this update
- Walnutsanity
- Player Buffs
- More customizability in settings, such as shorter special orders, ER without farmhouse
- New Remixed Bundles
											
										 
											2024-07-07 16:04:25 +03:00
										 |  |  |     for skill in pack.skills: | 
					
						
							|  |  |  |         content.skills[skill.name] = skill | 
					
						
							|  |  |  |     pack.skill_hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # register_quests | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     content.registered_packs.add(pack.name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def register_sources_and_call_hook(content: StardewContent, | 
					
						
							| 
									
										
										
										
											2025-04-08 12:37:45 -04:00
										 |  |  |                                    sources_by_item_name: Mapping[str, Iterable[Source]], | 
					
						
							| 
									
										
										
											
												Stardew Valley 6.x.x: The Content Update (#3478)
Focus of the Update: Compatibility with Stardew Valley 1.6 Released on March 19th 2024
This includes randomization for pretty much all of the new content, including but not limited to
- Raccoon Bundles
- Booksanity
- Skill Masteries
- New Recipes, Craftables, Fish, Maps, Farm Type, Festivals and Quests
This also includes a significant reorganisation of the code into "Content Packs", to allow for easier modularity of various game mechanics between the settings and the supported mods. This improves maintainability quite a bit.
In addition to that, a few **very** requested new features have been introduced, although they weren't the focus of this update
- Walnutsanity
- Player Buffs
- More customizability in settings, such as shorter special orders, ER without farmhouse
- New Remixed Bundles
											
										 
											2024-07-07 16:04:25 +03:00
										 |  |  |                                    hook: Callable[[StardewContent], None]): | 
					
						
							|  |  |  |     for item_name, sources in sources_by_item_name.items(): | 
					
						
							|  |  |  |         item = content.game_items.setdefault(item_name, GameItem(item_name)) | 
					
						
							|  |  |  |         item.add_sources(sources) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for source in sources: | 
					
						
							|  |  |  |             for requirement_name, tags in source.requirement_tags.items(): | 
					
						
							|  |  |  |                 requirement_item = content.game_items.setdefault(requirement_name, GameItem(requirement_name)) | 
					
						
							|  |  |  |                 requirement_item.add_tags(tags) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hook(content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def prune_inaccessible_items(content: StardewContent): | 
					
						
							|  |  |  |     for item in list(content.game_items.values()): | 
					
						
							|  |  |  |         if not item.sources: | 
					
						
							|  |  |  |             content.game_items.pop(item.name) |