-
Notifications
You must be signed in to change notification settings - Fork 0
/
_targets.R
234 lines (204 loc) · 11.7 KB
/
_targets.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
## Section: Setup (don't mess with this part)
##################################################
## Load your packages, e.g. library(targets).
source("./packages.R")
## Load your R files
lapply(list.files("./R", full.names = TRUE), source)
## Section: Pre-made product and quantity vectors
##################################################
# Tier 3 buildings and approx quantities
tier_3_buildings <- c("Desc_Cable_C" = 0,
"Desc_Cement_C" = 0,
"Desc_IronRod_C" = 0,
"Desc_ModularFrame_C" = 0,
"Desc_Wire_C" = 0,
"Desc_Rotor_C" = 0,
"Desc_IronPlateReinforced_C" = 0,
"Desc_SteelPlate_C" = 0,
"Desc_IronPlate_C" = 0)
tier_3_building_qty <- c(754,
132.4,
80,
66.2,
128,
146.2,
332.4,
100,
300)
# Pre tier-3 buildings with quantities
pre_tier_3_buildings <- c("Desc_Cable_C" = 0,
"Desc_Cement_C" = 0,
"Desc_IronRod_C" = 0,
# "Desc_ModularFrame_C" = 0,
"Desc_Wire_C" = 0,
"Desc_Rotor_C" = 0,
"Desc_IronPlateReinforced_C" = 0,
# "Desc_SteelPlate_C" = 0,
"Desc_IronPlate_C" = 0)
pre_tier_3_building_qty <- c(754,
132.4,
80,
# 66.2,
128,
146.2,
332.4,
# 100,
300)
## Section: INSTRUCTIONS
##################################################
# This script lets you optimize relative production rates of some set of components,
# given some known availability of raw resources.
#
# I chose this as a goal because the production planners I knew of would let you design
# a factory that would produce components at some desired rate, but most of the time I don't really
# have a good idea about what rate would be "best". What I wanted to do instead was to have a calculator
# that could look at a set of available resources, and an amount of components that I wanted to make,
# and then spit out a design for a factory that would use up all the resources and also make the components
# I wanted at rates that were proportional to how much of each I needed (e.g for some milestone). This
# to me seemed to be a satisfactory (ha) way of deciding on a "best" rate that (at the time of writing)
# wasn't implemented in existing calculators.
#
# I have set it up so that the optimization is relatively automated but
# it is still not necessarily intuitive what inputs should go where in the script.
#
# There are 4 sections which need to be set by the user before running the script.
#
# First, get the full table of recipes by running tar_make(RecipeData) in the console.
# Then run tar_load(RecipeData) to load the table into the environment.
# The full recipe table can then be inspected by running View(RecipeData$AllRecipes). This
# will bring up a table of all the recipes which will be helpful for finding most of the other
# required inputs.
#
# Next, enter any alternative recipes you've unlocked by replacing c(NULL) in
# the available_alternative_recipes target with a comma seperated character
# vector of the recipe 'slug' names for the unlocked alternative recipes.
# You can find the 'slug' names from the full recipe table.
#
# Example: if you've unlocked the steel rotor and recycled plastic alternate recipes,
# you could replace c(NULL) with c("alternate-steel-rotor", "alternate-recycled-plastic")
#
#
# Now, go to the Opt_products target. Here, put in the items you want to produce.
# These have the be product names, again as they appear in the recipes table.
# Enter these in the form of a named vector like
# c("product name" = some number, "another product name" = some number). These can be set to any numbers now,
# it's a leftover from the old solver that I still need to fix but I'm lazy.
#
# Example: If you want to make rotors and reinforced iron plates, you could set this to
# c("Desc_Rotor_C" = 50, "Desc_IronPlateReinforced_C" = 50)
#
# Next, provide your available resources in the same format as the desired products.
# MAKE SURE EACH AVAILABLE RESOURCE IS NEGATIVE
#
# Example: If you have 120 iron ore and 60 copper available, this would be set to
# c("Desc_OreCopper_C" = -60, "Desc_OreIron_C" = -120)
#
# Finally, in the LP result target, you need to set one argument in the factory_binary_search
# function:
#
# 1. reqAmt: I made this calculator to find the factory that produces some set of items
# at a rate relative to one another that is proportional to the amounts of each item that
# is required for the objective. If you are using the script to complete an objective,
# it makes sense to set this argument equal to the number of each product that is required for the objective.
# Otherwise, you can enter numbers so that they reflect how much more of some component you want relative to the others.
# Enter these numbers in the same order the product names appear in the Opt_products step.
## Section: Targets plan - Begin control script
##################################################
## tar_plan supports drake-style targets and also tar_target()
tar_plan(
## Section: Data cleaning
##################################################
# The url to the recipe data (Greenys github repo)
tar_target(Recipe_url,
"https://raw.githubusercontent.com/greeny/SatisfactoryTools/dev/data/data.json",
format = "url"),
# A file that has the recipe data from the game files
tar_file(recipe_json,
here::here("data", "recipe_jsons", "Docs_utf8.json")),
# Clean up the recipe data from the recipe json
tar_target(RecipeData_json,
clean_recipe_json(recipe_json)),
# Download the data from the url
tar_target(RecipeData,
get_recipe_data(url = Recipe_url)),
# The names of the alternative recipes you've unlocked
# Set to c(NULL) if none have been unlocked
tar_target(available_alternate_recipes,
c(NULL)),
# Make a list holding the current recipe table and its associated graph
# from the alternate recipes that have been unlocked
tar_target(current_recipes,
make_current_recipes(RecipeData_json, available_alternate_recipes)),
## Section: Factory optimization
##################################################
# Component names to produce (set each equal to 0),
tar_target(Opt_products,
tier_3_buildings),
# Provide available resources (negative values)
# Leave resources commented out if you don't have access to them yet
tar_target(available_resources,
c(#"Desc_OreBauxite_C" = -10000,
"Desc_Coal_C" = -660,
#"Desc_RawQuartz_C" = -10000,
"Desc_OreIron_C" = -720,
"Desc_OreCopper_C" = -210,
#"Desc_OreGold_C" = -10000,
"Desc_Stone_C" = -240,
#"Desc_Sulfur_C" = -10000,
#"Desc_OreUranium_C" = -300,
"Desc_Water_C" = -9007199254740991)), # -9007199254740991 is the total amount of available water on the map. Change if
# water is limiting and you have a better idea about how much you can access
# Use binary search to try to find a factory that....
# a) Produces the desired products at rates proportional to the
# amount that are required
# b) Uses resources up until all of at least one available resource is consumed
tar_target(binary_LP_result,
factory_binary_search_continuous(Opt_products, # DON'T CHANGE THIS
current_recipes, # DON'T CHANGE THIS
available_resources, # DON'T CHANGE THIS
req_amt = tier_3_building_qty, # How much of each product is required. Same order as Opt_products list
# max_rate = 1, # Starting upper bound for the the search space of production rates
whole_number_factories = FALSE, # Do you want a solution with integer factories (do you not want to worry about under clocking factories)
slack = FALSE)), # Likely, you will produce extra intermediate components if this is set to TRUE. Under clocking is so easy to do now
# though that it's probably best to keep this to FALSE, just remember not to panic when a result tells you to make
# 1/8th of a factory or something
# If slack = FALSE, the solution will try to find a factory that makes products in exactly the rate ratios you indicate
# regardless of if such a solution leaves some resources unconsumed. slack = TRUE will produce extra products
# beyond the requested rate if it can do so without sacrificing the minimum production rate of some other requested product
# Clean up the output into a format that's ready for plotting in cytoscape
# To open in cytoscape:
# 1. Start cytoscape
# 2. Test connection by running: 'RCy3::cytoscapePing()' in the console
# 3. Run 'RCy3::createNetworkFromIgraph(tar_read(CytoscapeReady_binary))'
# in the console to open the network in cytoscape and customize.
#
# Network notes for future me:
# The yFiles orthogonal edge router layout
# does a good job of placing/clustering nodes in a layout that makes sense
# for organizing factories (minimizes edge overlaps).
#
# Use the "Curved" style. This should work right away but if not...
# * edge labels from the "flow" column
# * Node fill color from "producedIn", Mapping type: discrete, use whatever
# color assignment you like
# * Node name from "name" col (duh)
# * Node size from "nFactories" w/continuous mapping. Adjust till it looks nice
# * Adding in a legend w/the extension doesn't hurt
tar_target(CytoscapeReady_binary,
clean_binary_lp_results(lp_result = binary_LP_result$soln,
recipeData = current_recipes$data_frame,
recipeGraph = current_recipes$graph,
products = Opt_products)),
## Section: Targets for testing stuff
##################################################
tar_target(current_recipe_matrix,
make_recipeMatrix(names(Opt_products),
current_recipes$graph,
current_recipes$data_frame,
"component")),
# A function to find the limiting resource
tar_target(resource_consumption,
find_limiting_resource(current_recipe_matrix,
binary_LP_result$soln,
available_resources))
)