Code Monkey home page Code Monkey logo

factoryplanner's Introduction

Factory Planner

Factory Planner is a mod for the game Factorio. It is published in zip-format on the Factorio mod portal, which allows it to be downloaded and updated by players in-game.

It enables players to plan out their production in detail, specifying the recipes, machines and modules to use. It allows for conceptual separation of assembly lines through the use of separate floors that can be nested infinitely. There exist calculators on the web that can do this already, but a big advantage a mod has is that it can incorporate the exact combination of mods the user has installed, with up-to-date information, which is something that external solutions struggle to provide.

My focus when creating the interface for this mod was on making it as clear and intuitive as possible while offering all the features that power users need. To that end, users should be able to get started on their first plans relatively easily, after which they can gradually explore all the functionality that is offered. The interface was created with all the modern design standards and interaction paradigms in mind, making it conform well to both user's expectations and the rest of the game.

There is a public project board organizing what's on my radar. Suggestions and bug reports are centralized here on Github. Feel free to join the Factory Planner Discord to talk to me and others in a more casual way.

Contribute

If you want to contribute to Factory Planner, please join the Discord and talk to me about what you have in mind first. I'm happy to hear about any ideas you have, but this mod is still in active development and I might already have a plan for what you're thinking about. You can of course also open an issue to talk about your ideas.

Localisation

Localisation of Factory Planner is handled entirely through a separate project on Github. If you're interested in helping out, feel free take a look. There are further explanations on the project's page. If you have any technical questions, please open an issue on that repo.

License

This mod is licensed under MIT, with the exception of the localisation, which is in the public domain.

factoryplanner's People

Contributors

claudemetz avatar ctgpi avatar curiosity-a avatar egerlach avatar eugene-khorev avatar fiona avatar francoiscampbell avatar pfqniet avatar raiguard avatar scottmsul avatar tabasavr avatar talshorer avatar tburrows13 avatar zorbathut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

factoryplanner's Issues

Floor Library

The main idea is that users won't have to re-layout the same recipe chain over and over. This could be achieved in a number of different ways, but this seems like the most sensible to me.

Split the side subfactory list into two sections, one as normal and the other being a list of 'subfactories' that can be used elsewhere.

These 'subfactories' need to be based on a recipe, they are basically subfloors. Not quite sure what this would look like, probably a fixed first recipe as on subfloors and unchangeable products.

They can be configured and are reduced to a 'simple' input->output equation for performance, and then used in proper subfactories in place of defining subfloors oneself.

How the interaction will look like is to be determined. One idea is to have the user pick the recipe first and then modifier-click it to pick a floor from the library to use. Another could be a choice built into the recipe picker itself. There are other possibilities too.

These recipes would be linked to the 'canonical' version the library, meaning if it changes, it'll change everywhere it's used. This is a bit problematic since you might want to keep an old plan as it is built, but change the library for future builds. Not sure how to address that. The user could just duplicate the old one and modify it then, but that creates a lot of duplicates over time. One solution could be to duplicate it and bake the previous ones in, meaning it'd remove them from the floor library and insert a 'real' version everywhere it was used.

The input->output equation could potentially be used as a performance boost for normal subfloors as well, although it might not work with the matrix/simplex solver.

Remove written tutorials

The written tutorials are just bad and outdated now, so I should remove them. Ideally, there'd be a tips-and-tricks based replacement, but that's so much work that I'm not sure I want to spend.

Combine machine and beacon dialogs

There are a few tasks related to the machine dialog that could be done at the same time.

In addition:

  • Hide the fuel_frame if it doesn't apply.
  • Include the module_config stuff in that same file (if that doesn't make it too gargantuan)
  • Remove big + buttons (including their custom style) from the production table modules, instead adding a suggestive + onto the machine/beacon button if there are empty module slots, to save some space.
  • Add a reset button to the dialog

Mind Reading

Suggestion

Why does the mod not read my mind? That'd be very helpful. Thanks.

Recipe validation uses simpler algorithm than recipe picker

The recipe picker has a more refined way of filtering recipes, while the prototype migrator just checks for existence of the recipe prototypes. Not easy to fix, since the validator doesn’t get a player reference, which this kinda needs. Not sure what to do. Will probably end up passing a player along. Could also think about storing a player (or force?) in the data structure, but that feels like a code smell.

Solution would be to use the recipe picker algo for validation as well, although that is a bit tricky potentially.

Context

image

Rocket Silo Recipe Crap

Not even sure what is going on, I will have to just look at it from first principles, work out all the possible scenarios, and then rewrite the generator code to deal with it.

One thing Rai mentions below it a 'wizard' kinda UI where you pick the different parts of the rocket launch process in order. Might be the only solution to the problem according to him. I would hate to have to do so much GUI work for it, but if it's the only way, then so be it.

image

Ore/oil utility

Utility that allows users to select resources on the map to track. The mod will track output, and compare it to the consumption of the attached district, so the user knows if all they planned out will be fed properly with the selected resource fields.

Can also alert the user if the tapped resources don't produce enough anymore, if they want to know.

This can also have a static calculation portion, where you select a few prototypes and it tells you how many miners you need to satisfy the whole demand, or the currently missing demand, etc.

I'm not quite sure how difficult this tracking will be to implement. There are existing mods that do it, but hopefully I can do my own version without too much trouble, or performance impact.

The extension of this would be a way to automatically build miners on resources you select, but that seems like quite the hard task, for which other mods already exist. So maybe I could integrate with them, but yeah, low priority for sure.

Add basic arithmetic to several textboxes

Let users enter basic arithmetic in textboxes, and convert them on_gui_confirm. (Instead of instantly confirming the dialog when doing so). Applies to the item picker, beacon total, maybe others.

Will not allow me to use the vanilla numeric textfields, will have to implement those checks myself again, which is annoying. A better solution might be to have a button that brings up a small calculator that you can use right in there. Might be fun to do.

View state overhaul

There are a few ideas on how to improve view states that are best implemented together.

Another fringe idea that was had is the ability to scale a factory from pretty much any value, be it machine amounts, item amounts, or anything else. This functionality already exists on ingredients, and it could be expanded to all numbers that make sense. It's a bit weird, and it would not be permanent, instead adjusting either the line percentage, or the top level product amounts. Either way, it'd be pretty messy, there's lots of details to work out.

https://discord.com/channels/600791114814980141/600796714558947360/1127863509565325312

Reduce global clutter even further

I'm quite close to no more global clutter, besides a few necessary ones. Should try and root the last few out.

Might not need to have any necessary ones, could use the GLOBAL_HANDLERS system to call random one-off functions like main_dialog etc.

Move optional product icons in subfactory list to the right

Not sure why I didn’t do it this way from the start. Possibly because it didn’t work out since those buttons are so hacky. Should try putting the normal name in its own flow, and have the icons in another, and have the name one stretch. Something like that.

New way to handle defaults

Currently, the default machine/fuel/module/beacon/etc are all set in preferences. This works fine, but is a bit clumsy. What if, instead of doing that, the player could just set the defaults in the machine dialog when changing something about a specific line. That seems like a much more direct way to accomplish the same thing, in a format the user is already familiar with.

There's many ways the UI for this could work. One way is to have the user set all the fields as they desire, and then click a 'save as default' button, which takes the whole set as the default for this recipe category or similar. On the other end, there could be 'set as default' buttons for every kind of input field, allowing them to set things with granularity. This possibly has fewer technical/UI issues, even if it might be a bit more clicking for the user. Will have to work this out as I go.

Machine module defaults would likely be per recipe category, same for beacon defaults. The beacon prototype itself is a default too, but it won't effect the modules I don't think. Fuel default will be separate I think, just per category or combination of categories.

The current defaults wouldn't be visible to the user anywhere as an overview. They would be visible when editing a machine, which are then of course only the defaults for that particular category/whatever. This isn't really an issue I don't think.

Something that would be lost with this is the ability to set defaults for multiple categories at once, for say upgrading to assemblers 2 in every category. This is a definite regression, but possibly an acceptable one. There could potentially a way to have the ability to set a machine/fuel/whatever as default for 'everything', ie. everywhere it is used. Might be technically difficult to do this.

Implementation-wise, this would be done as a default-none set of tables, meaning the defaults table is empty at first, and only filled in if the user sets a specific default. If a default doesn't exist, the mod just picks one, most likely the first in the list.

This impacts vast parts of the codebase. It means things can be removed from preferences, prototyper, loader, locale, and more. It also means the new system needs to be built, including validation/migration, which will likely be painful.

This best waits until the machine/beacon dialogs are combined, since the UI will need to fit in there.

Also, this should address the following issue, for which I can't think of another solution.

Set item amount by current view state

At the moment, you can only do this by item amount per timescale, and it switches to that view when you open the dialog. I should offer the same for belts and others, which shouldn't be too difficult to implement. Ideally, it would be made generic for everything of course.

This should also probably turn it into its own proper dialog, so the generic dialog system can be discarded.

Lab utility

Could have a utility that helps handle the research part. It takes into account how much science you put out, and can calculate the number of labs you need. This obviously depends on the speed of the currently running research, which makes it tricky. Could use the worst-case number, maybe.

What could also come into play is a way to select existing labs, and track them. Combined with taking a look at the running research, it could alert the user if the number of labs is too low, if they desire.

It would be fun to collect usage data

This is obviously tricky, as a mod can’t access the internet. The solution would be to have a spot where the user can export their usage data and submit it to me manually somewhere. This would make this whole thing very low volume most likely.

Collecting the data itself could be annoying, depending on the detail I want. The very basic version would be to grab any input action and count them. Since most everything goes through them, that would be at least somewhat interesting I’d assume.

Then, even if the data is collected and submitted, I’d need a way to analyze it, which might be quite a bit of work too. Sounds intellectually interesting though.

Integrate mod settings into preferences

Basically I think this is a great idea and I should do it, but it might make the preferences dialog look a bit ugly for a time, as it’ll change in appearance a lot as the big features are implemented.

Also allows me to get rid of the settings screenshot and the machinery attached to that.

Utility dialog subfactory/floor-actions

Have several actions that would apply to the whole subfactory or the current floor, to allow better managment of complex setups

Actions include: Setting all machines or fuels to the default values, Setting/Upgrading/Downgrading/Removing all modules or beacons, Consolidate identical recipes on a floor to the last one/an even later one to satisfy all demand, set machines/beacons/modules to current defaults, multiply product amounts by a certain value, ...

Copy/paste makes this less necessary. It still has its uses though. The biggest issue currently is that I don't really know how the UI would work.

Add preference for users to pick the view states they want to see

The current setup of showing 4 works fine, but there’s two more I want to add, and there is no space for those.

The solution is a preference where the user can pick up to 4 out of 6 views (min. 1 obviously). The system works the same on the surface, cycling through the available ones, etc. The preference itself will just be a set of checkboxes with labels, which all disable when 4 total is reached, so the user needs to disable one first before adding another one.

Needs somewhat of a redo of the underlying system, as it is not laid out for this. Shouldn’t be too bad though. Should do this alongside adding the new views obviously, both because the system makes more sense with them in it, and that way I don’t need to deal with migrating it later.

Multiplayer Cooperation

Have the possibility to share subfactories with all players on the map (or force?). Every shared subfactory has an owner who can edit it, everyone else can just view it, to avoid complications with simultaneous edits.

Personal subfactories still exist, and are a separate category to the multiplayer one. This is reflected by their own header in the subfactory list.

Subfactory ownership can be transferred of course, and there should be a nice way to move a plan between shared and not shared. Probably inside the subfactory dialog. Moving a subfactory down from the end of the personal list could also move it to be a shared subfactory, and vice-versa. Maybe subfactories can also not be owned by anyone, meaning they can be taken by anyone without being transferred by someone else.

These categories need their own 'add subfactory' button in the UI, but all other buttons at the top can be shared. The spot that's freed up by removing the add button could be replaced by a subfactory search functionality.

Should also think about having the multiplayer controls (transfer, take possession, etc) in a little box above the subfactory info. Having all that in the subfactory dialog is probably too hidden. I might just remove that dialog then, and have a name edit button right in that new window. If I need space, I think the subfactory info box could be made smaller/removed by moving the stuff inside it elsewhere. Could also include the archive move button since that’s kinda related.

Can think about having custom subfactory categories/sub-lists that people can add, but eh, feels like a bit much. The global District idea kinda replaces this anyways, in some ways.

Fix Factorio's rounding of numbers on buttons

Been an issue since forever, but not super easy to deal with.

There technically is a way for me to pre-format the number so the game shows it correctly, but it'd have to know about the details of how the button formats the number depending on the order of magnitude, which makes it quite complicated and potentially problematic performance-wise since there are a lot of these buttons in the UI.

This could probably be done on all buttons without an option, since it just kinda makes sense. It‘s better to overprovision belts than to underprovision them for machines, for example. At least machine and belt counts should have this, as these are the ones with the rounding option anyways.

Maybe there are other kinds of buttons where this is not desired, and proper rounding should be done instead. The vanilla behavior of showing 1.09 as 1.0 probably doesn‘t make sense anywhere though.

https://discord.com/channels/600791114814980141/600796714558947360/1092120575377408100
https://mods.factorio.com/mod/factoryplanner/discussion/640db4b88e10893c2b9abadd

Factory search

This would either be an inline search field, or a modal dialog if more advanced functionality is desired. This makes even more sense with more subfactory categories. Could also have a permanent search field, although that might be a bit too much prominence for a potentially niche feature. Search would search subfactory names and products/ingredients?, ideally.

Production verifier

The basic idea is to have a selector in the mod on any subfactory where you can select your existing setup and it’ll tell you how far off the planned production you are.

It would be very sweet if it converted it into a proper plan and compared actual production to the planned one (say the plan has 5 assemblers 1, but the actual setup has 3 assemblers 3, and it tells you how close that it). This is fraught though, as we know.

So as a first version, it could just compare machines including modules etc and diff those counts, which should be pretty straightforward.

This’ll require a new dialog most likely, which means some GUI work, but not too much.

It could also serve as a base for further such features, as it’ll be easier to do all this in an incremental way rather than the full factory import all at once.

Blowing the roof off

Currently, there exists a single District that houses all the factories for the player. What has often been asked for is a way to combine the inputs/outputs of all their factories in one place, and have one factory feed another potentially. The solution to this is the District, which combines everything from all factories into an overview, and allows them to interact in more ways than they currently do (which is not at all). What exactly the interactions will be is to be figured out.

It is important to note that it would be totally fine to just have a single district all game, kinda like you have now. Most of the time, players only have one monolithic factory anyways, so that's best modelled by a single district. Still, it's pretty easy to give them the chance to have multiple, if they so desire.

UI-wise, I imagine this replacing the right side of the main interface. The factory list would stay as it is, but the right would be replaced with the list of districts, which take up a lot of space to display the aggregate items, power, and the utilities described in sub-issues. They can switch between districts there, which updates the factory list on the left. Then they can of course go in/go out of a district to see the current UI with all the details. There will be UI challenges with this for sure, but I think they can be figured out.

This has implications for multiplayer. The current thinking is that Districts are per force, so every player sees each District. It needs to be this for the science/etc tools to make sense. Inside them, there are shared factories that count towards the district totals, and private ones that don't. So everyone pools in the main stuff into the shared area, but one can have plans off to the side as well. Archive doesn't ever count towards the totals, of course.

This also offers some surface area to integrate with the actual factory in more ways, which is something I think could be an important differentiator to online calculators. These are in separate issues below, and would be presented in the district list, next to the item totals etc.

Bot request functionality for top level ingredients

Think about generalizing the item request code so the top level ingredients can have request functionality as well. Icon for this should be a logi (or is it construction?) bot. Would lose the functionality of the button showing the status on it, which might be too important to get rid of.

There would only be one system for both machine/module and item requests, meaning you can’t do both at the same time on the same subfactory. Need to make sure that all works properly.

Seems like a nice idea, but also seems quite complicated for a minor feature.

Dealing with Byproducts

The traditional solver can't have the user add byproduct recipes, to consume byproducts explicitly. This shouldn't really be too complicated to handle, it would need to pull from the pool of byproducts instead of products to set its demand, but yeah we'll see.

This will require the UI to be updated for this. Most byproduct shenanigans are already in place for the matrix solver, so it should be a simplification of that, ideally. This is quite close to the calculating by ingredients idea, so we'll see how those interoperate.

Make sure to check out how line satisfaction will deal with all of that.

Consider bringing back machine dialog button numbers

They are sweet to have, and I think I should have them, but they are also very annoying to calculate if one wants to take into account all the circumstances.

Might make sense to wait for the solver rewrite with this one, and have the solver offer an easy method for it.

If I don't bring them back, the machine and fuel buttons could become choose-elem-buttons to save space. Makes it one more click though, which I dislike. But would be consistent with the beacon dialog.

https://discord.com/channels/600791114814980141/600796714558947360/1102270888101023804

Performance Improvements

Just some ideas that would potentially make sense

  • Opening the item picker to edit seems particularly slow

  • Add the satisfaction calculations as far up the chain as possible, for better performance

  • Could re-add caching of dialogs that are slow. bring_to_front() makes this possible again. Will be a significant effort to change the code around to support this though, both for modal_dialog.lua and the individual dialogs

  • Maybe a faster refreshing method for subfactory info that only updates energy and pollution, since that's way more common than the other stuff in that box

  • Look into more caching; subfactory tostring, subfactory modset diff, etc

  • Improve check_module_compatibility methods: This runs often and pretty much always on a set of modules. Could likely be batched better, as well as caching some of the results if sensible. It'll depend on where exactly this is used.

Remember position for modal dialogs

Probably doesn’t make sense for all dialogs, since some change in size. Maybe that’s fine though. Not remembering their position is a kind of data loss, from a certain point of view.

Add context menus for modifier actions

Should definitely do this, very powerful idea. Will require quite the refactor of the whole actions and tutorial tooltip system, which is fine since it’s kinda jank anyways.

Would probably remove the tutorial mode tooltips, both for simplicity and performance. If you want to learn about the shortcuts, they’ll be on the context menu.

This would also make space for more actions, if not every action needs a modifier-click. Less essential features like ‘cut’ could be implemented and just not given a shortcut, if that was the thing preventing it from being added.

Has the issue that right click now always brings up the context menu, and any actions tied to right click must be moved. We’ll see how disruptive this will be, but some habit changes will be needed, can’t be seamless unfortunately.

Additionally, some things that don’t use this system (like alternative subfactory-add-mode) should probably switch to it. It didn’t before because that made the tooltip different than I wanted it to be, but if the tutorial tooltip is removed, that’d be fine.

In that vein, the tooltip could still mention some specific, special modifiers that are very important in addition to the normal left click if desired. This wouldn’t be some system though, but just part of the fixed tooltip string. Would need to make sure it only mentions actions that are possible regardless of context, ideally.

This 'modal dialog lite' functionality could also be used elsewhere, like for example a custom module picker instead of using choose-elem. So I should try to make it somewhat generic to use.

This could go hand in hand with this idea: #47

Should also get rid of tutorial dialog, and place the example factory in preferences.


Features that this could enable:

  • ‘cut’ in addition to ‘copy’ and ‘paste’

TODO:

  • Rejigger modifier-clicks so right click is always left for context menu
  • Make action system work for actions without modifier-click
  • Fix dimmer for compact dialog
  • Allow disabling menu for context actions
  • Remove tutorial tooltip preference and update text to mention context menus
  • Convert all gui click handlers with use more than left click to this system
  • Flip context menu to the left when location is closer than 300? units to the right edge of the screen
  • Consider which new context menu features to add
  • Write changelog
  • Maybe move tutorial section to the preferences dialog?

Rocket silo calculation incorrect with productivity

I apply the productivity effect to the whole time the silo takes, which doesn't take into account that the launch sequence time doesn't change with productivity.

Fixing this is incredibly messy with the current system. I think the production_ratio related portion needs a serious refactor.

One idea that just came to mind is to split the production_ratio up into a machine production ratio and a product one, since they can obviously be different for stupid rocket things

Power production utility

It would be great to have a utility that helps you figure out how much power production you need to satisfy your needs. This utility would have different ways to configure the different ways of producing power (solar, chemical, nuclear), and maybe propose solutions to you.

Technically, this is quite complicated, since power setups involve a lot of prototypes that interact in specific ways, so it's lots of generator stuff to figure out. It would of course integrate with the district item and power pools.

This could also integrate with the real world, tracking power consumption (and maybe even production), and alerting the user if it clashes with the current plans.

Need to think about this one, I could also implement power production as normal recipes that can be used alongside others. This is quite tricky, as powder production doesn't quite fit the model of recipes, but it could. If I add energy and heat as items, it could fit into the existing system quite well. The advantage of making it part of normal factories that the supporting infrastructure can be right alongside the power production.

Back/Forward

Same kinda ideas that browsers etc have, just a way to move around with context. Not sure how valuable it’d be to users though.

Should be pretty trivial to implement with the new context system, just keep track of the selected IDs, since there’s only ever one now, and set those again when requested. Queues like this are a solved problem nowadays, so I can just look up a sensible algorithm.

The only issue I can think of is when something that you want to move to became invalid. Not quite sure how to detect that. I guess if the object isn’t cached anymore, it’s not valid anymore, just like the current context validation checks it. If it still exists, it should be fine to go to.

Need to figure out where to put the buttons for this. I‘d put them to the right side of the title bar (together with undo/redo maybe), and center the title caption in the middle of the window, with drag bars on either side. Can consider putting the pin icon somewhere else as well, since it’s related to the factory, less to the whole interface, in a way.

Rename the mod

I am so fed up with the name. It's deadly boring. Maybe I rename it for the 1.2 release. Details in a personal note as not to spoil the surprise.

Update script to create release on Github

Looks like I should create a local git tag first on the ‘Release X’ commit, then create a release using this, and possibly update it with the changelog etc. Maybe the changelog can be in the git tag as well? I’ll have to see. Seems easy enough though.

Undo/Redo

Not quite sure how this would work without needing to custom-code the reverse of every interaction, which seems like a bit much. Maybe it’s not though, and there aren’t actually that many data-modifying actions that would need to be coded up. Will need to go through them all to get a better picture. Would maybe also be a nice refactor, so every data-changing action goes through the same spot (where the undo action is stored), making the code cleaner.

Still, would have the issue of determining whether an undo/redo is even possible if the data set changed in some way in the meantime. Although maybe not, if every action has a reverse, you can’t do any action that leads to an invalid state because every change will also be the most recent stored undo, so the sequence should still work.

Alternatively, one could just store the entire state of the world each time a modificative action happens, and restore that when requested. Not sure how bad that would be for performance to pack up a subfactory on every action, will need to test.

For extra (performance) credit, one could try packing up only the smallest possible object. So a subfactory name changes → pack subfactory, but if a line percentage changes, just pack up that line. Easily done on the packing side, but not sure how properly restoring that would work. Maybe it’s not too bad.

Go further with event handler

I should go further with the event handler, splitting action-based handlers into individual methods and calling those directly.

The issue with this is that they often share some code, which would then be duplicated. I could work around that by writing a setup method that pre-processes some of the data before the real handler is called.

Also, consider if the event_handler code can be refactored a bit, it has become quite clumsy over time. But maybe it has to be that way, inherently.

SE fuel choice issue

It is caused by the machine supporting multiple fuel categories, so it has to pick the default from one of them, since there is no way to define a default for combinations of categories. While that could theoretically be implemented, practically the exponential nature of those choices makes it a bad idea.

The parent issue would address it by making default choices being picked in the machine dialog, where it could save defaults for specific combinations of fuel categories in the background, invisible to the user. The defaults system needs to be able to do this, of course. A potential easier way to include them is to combine the categories as a string (ie. chemical_jerry-can) and store defaults that way. I'll have to see how it shakes out.

image

Solver bug with catalysts

I haven't investigated this bug too much yet, but it's related to catalysts. They are probably handled a bit weirdly by the mod, so I'll see if I can come up with a clearer system for them.

image

Time Travel

There's two categories of sorta time-travel ideas that I'd like to consider: Forward/Back and Undo/Redo. Both are similar, but different. I split them into two different cards.

Also think about whether I can do away with any safeties that were important before, but annoying now.

Improve matrix solver UI

The matrix solver UI is pretty unintuitive, and there's ideas to improve it that I should be able to do. Below are some suggestions by users.

So I am now aware the matrix solver is probably not adjustable, but depending on the interface with it, some of these might be feasible.
UI - In the popup, give details on the ranges for each possible resource, if it will increase or decrease, and specifically let you choose one of those. I don't mind producing extra petroleum, but I can't exactly consume more of it since I have zero.
Linearly Dependent - When this goes off from you selecting the "Wrong" unrestricted items, you can't unselect that last unrestricted item, but must either remove recipes or or turn the matrix solver off, which removes any void recipes or previously chosen unrestricted items.
Also, I would prefer being able to have a list of those recipes and be able to say "I prefer Recipe A over Recipe B, use A as much as you can then switch to B" or something like that.
Isolation. Subfactories, currently, are mere organization tools. They only make things look nicer, by hiding complexity, but don't actually act as seperate subfactories. Suggestion that the inside of a subfactory is treated entirely like a encapsulating class, such that its insides are completely blackboxed to any higher level factory. So for instance, you put a Koverox process in there, matrix solver on, and it figures out the loop. You go back up a level, and it just treats that subfactory as a "virtual recipe" which consumes 2 depleted uranium to make 1 enriched uranium.
Locking. Allow recipes to be "Locked" such that the matrix solver can't touch them, but has to work around them. As far as it is concerned, a locked "Gear" recipe just adds a demand to the system of producing 2 iron and consuming 1 gear.
Minimax. - Instead of absolute values of whatever, have ranges. All resources are +- infinite by default, but if you demand an output, it defaults to a minimum value given, You can lock that by adding a max. Inputs are the same, where you are inputing at least this amount. The matrix solver then runs inside those constraints, which you can narrow down until it is trapped at one chosen solution.

More stuff

image
image

More ideas

  • Try to prevent user from adding recipes that would make the situation linearly dependent. It still can by removals maybe? Or not. Still probably possible.
  • Add warning when solver produces bad result (0 or negative numbers)

Add in-mod changelog view

It would be neat to show the changelog in-game because it'll show to many more people. The button for it could be alongside tutorial and preferences at the top, or buried inside one of them (likely tutorial). Alternatively, that dialog could be renamed to be somewhat more general, and maybe get rid of the bad tutorials.

It could do the thing where it only shows you the changes you haven't seen yet (as well as the complete changelog if desired). I'm not quite sure how to do this exactly, as every player will need to be treated separately. One likely solution is to accumulate updates on a player until they open the dialog and then flush them. This is a bit weird since opening, closing, then opening again will show a different view the second time. Might want to delay the flush somewhat.

This reveals two technical deficiencies. First, this would require the changelog to be Lua-readable and in its natural format. Having to update a changelog in two spots is obviously dumb. There would need to be a separate file that contains the changelog in a machine-readable format (YAML or JSON), which is then converted into its usual and into its Lua form when building a release. This sounds like a somewhat fun exercise. The migration masterlist could also be integrated into this one.

Second, the migration logic and tracking needs to be more beefy. It is quite primitive currently, basically running any migrations that are above the version of the data in the save. This works great, but is annoying during development as it'll always try to apply that future migration. Changing the migration system to avoid this would be neat. The obvious solution is to keep track of the exact migrations that were applied and thus don't re-apply any. Could also be a hybrid of those two approaches. A similar system would be required to keep track of which changelog entries the user has already seen.

After this is done, the release script could also potentially create a release script on Github.

Another idea that could be done alongside this is the ability for me to write special messages for certain versions, highlighting an important change or a potentially confusing GUI change, just to have a closer interaction with users, most of which don’t read the changelog anyways. This would work the same way, only showing users things that are new to them. I could do a pop-up when these come in, but an ‘news here!’ icon somewhere in the main interface would be less obtrusive, and allow the user to engage with it on their own time, without disrupting their workflow and having them dismiss it without reading.

Rewrite data backend

Notes

They are just kinda stupid. A parent class with .valid and .class would be cool, as well as using metatables to avoid the silly duplication of all collection methods on every class. Will probably be a bit annoying to restore the metaclasses, but I think I can handle it now. LuaBootstrap::register_metatable might also play into this now.

Also, having generic add/remove/etc methods even though most of the time, there is only one class of object stored, is dumb, and should be un-genericized.

Should also use metatables to make accesses like factory[1] get the first subfactory. Trickier for places where there’s more than one class associated, will have to think about it.

Subfactories having a list of all floors in them is kinda weird, see if I can get away with dropping that list. Alternatively, maybe subfactories are dumb, and everything should just be floors. There’s probably a few issues with that, but it should be solvable. This would help with a lot of pain points that relate to the top floor being special etc.

Also, maybe Line should be split up into Line and FloorLine, which is special for the lines with subfloor. Makes the split a bit less messy, since they are basically two mostly distinct classes in one currently.

Consider renaming Line to Recipe (and integrating the recipe class into it since it’s tiny). Recipe is what it’s called in the GUI anyways, and Line is kinda bland, so why not.

Maybe collections should not have gui_position, but be a linked list instead. Saves on complication and keeping track of count most likely. If I could get rid of the index variable, collections could be simplified further to just the linked list. I’d still need IDs, which could potentially be a randomly generated UUID, instead of just incrementing a counter. Alternatively, I could have a separate incrementing counter that’s shared between all objects. If using linked lists, give each class iterator functions for easy traversal. Instead of having a complicated cached index to find things by ID, just have one global one (possible because IDs are globally unique) that gets you to the object, populated on_load by going through the whole data structure. This saves me any complicated caching structure, and allows me to find any object by just its ID, instead of needing all its parents IDs as well.

For subfactories specifically, maybe I Factories don’t have a list of them, but the Pool idea comes into play, where Factory is renamed pool and contains both the normal factory and the archive. Then, when multiplayer supports hit, it’ll contain all that stuff also. Then, I can think about having a single ‘ID space’ for subfactories, where the Pool just has a single list, and the members have flags to indicate where they should be shown. Would make some stuff easier. Prime issue is how to keep track of GUI ordering, since the above linked list won’t work for a central list. Could split GUI order out like I do for selected_X etc, but there’s details to be worked out.

For the few above ideas, it might make sense to have a parent class like CollectionMember that contains fields like next, previous (if I need that), parent, maybe others.

View state data (selected_floor etc) should probably be moved outside of the main subfactory objects and into a separate data structure. This is both the cleaner factoring, makes it easier to set and reset this data, and will be important for multiplayer subfactories in the future. Make sure to move the state reset code out of init.lua. Also, it should have a way to set more detail (like a specific line/machine/item/whatever) on it, so those parameters don’t need to be passed on for every GUI action (like opening the machine dialog, or similar). Maybe the additional detail is reset when the event is done, or it is just left to be overwritten by the next one. Also, maybe this rewrite can incorporate the addition of forward/back functionality. I‘ll need to research how that is normally done, but if every view is uniquely identifiable by a specific context table, then that table could just be stored and then re-stored on demand. Also, could have individually unfoldable subfloors with this system (activated by right-click on recipe).

Could rename Factory to Pool for the forthcoming pool idea, but that could also wait until that later point, since the rename would be pretty straightforward.

Make sure to drop Items having Product/Byproduct/Ingredient as their class, makes things complicated for no reason.

Input-based calculation

This is the most-requested feature currently. People want to set an ingredient amount, and have the factory spit out how much they can produce with that. This is quite linked to byproduct recipes.

There are quite a few ways to do this, and all of them are quite invasive to the mod. I've come to realize this isn't just a side mode that can be enabled, it's basically wholly different, although in an interesting way: It's the (exact?) inverse of the current approach. Products become ingredients, byproducts become "by-ingredients" (patent pending).

This fact makes it potentially much easier to implement since there's not a wholly separate mode, but just the inverse of the current one. Still though, having the solver be generic enough that it can be flipped on its head will make the code quite a bit harder to understand. The UI will also have to be very adaptable for this, and might need some fundamental changes to make it make sense.

I think a fundamental requirement should be that a factory is either input- or output-based, never both and never (at least easily) toggle-able. Ideally, the underlying structures in the data backend would be generic, so no matter which mode is used, the same underlying variables store the data. Only a single flag determines how they are to be interpreted by solver and UI. I'm not sure if the approaches are quite that mirror-able, but it would be great if they were. Otherwise the complication would be through the roof.

Either way, there is a ton to work out, but this idea will need to be woven into the fabric of the solver rewrite from the start I feel. Maybe if the cognitive load of the rewrite and all that entails is too big, I won't consider it right away, but it would be less wasted work that way. We'll see.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.