A Weird Imagination

Devlog: Supply Challenge Plus (2 of 2): implementation

Posted in

The problem#

Last week, I talked about the modifications I and others wanted to make to the Supply Challenge scenario that comes with Factorio. This week I'll talk about actually making those modifications.

The solution#

If you just want to play the modified version, you can install my mod Supply Challenge Plus (source code on GitHub). The Mod Portal page describes what changes it makes and has screenshots of the UI with various choices for the settings to customize it.

The details#

Scope of first version#

As I had a planned game when I wanted to play the Supply Challenge without a time limit, I wanted to develop it as quickly as possible. This is often called making a minimum viable product or the "worse is better" approach to software development: get something done instead of overengineering a complete product.

I decided the necessary features were:

Licensing#

Quick note on licencing, since this project is explicitly a derivative work of code from Factorio, literally started by copying code out Factorio: the Factorio Terms of Service state:

Any adaptations or works derived from the Factorio assets are permitted to be included and distributed as part of your mod. However Wube Software Ltd. still retains all rights and license to these assets and the work derived from them, and reserves the right to request removal of these assets from your mod.

Which I interpret as meaning that this is an acceptable concept for a mod. I intentionally chose the Unlicense to not be appearing to claim any rights and in the LICENSE, I clarify that the Unlicense applies to my modifications, not to the original code from Factorio.

Distributing a scenario#

In the interest of simplicity, I did not yet try to adapt the code to work on arbitrary maps, keeping it as just a scenario. Technically, scenarios can be distributed on their own, but in practice it's much simpler to wrap them in a mod. So I started my mod by just copying the Supply Challenge into a mod. As the mod structure only requires an info.json file, this just means putting the scenario in the scenario/ directory next to to the info.json file.

Settings for a scenario#

Factorio provides a mechanism for mods to define settings, which can be read in any runtime code, including the control.lua of a scenario. To read a setting, just use settings.global["name-of-setting"].value (for a "runtime-global" setting, which all the settings in this mod are). The player sets the settings on the mod settings tab of the settings dialog accessible from either the main menu or during a game on the system/pause menu.

It would possibly make sense for some settings to be selected upon starting the scenario and not be able to be changed afterwards (e.g. whether the timer is used). As Factorio does not provide a way to enforce this, the mod could save the setting values in the save file when it first starts the map and ignore the settings afterward. I decided this wasn't worth it: players can switch between timed and untimed in the middle of a game if they really want to; I see no reason to stop them.

Pacifist compatibility#

The first and simplest change was making the Supply Challenge still work when Pacifist had removed the military items it expected to require in some of the levels (leading up to the Military Science Pack). There was already code to look for missing items, so all I had to do was modify that code so it omitted them from the requirements instead of showing an error and refusing to load. I put this change behind a setting so it wouldn't trigger unexpectedly.

Rethinking the timer#

The obvious meaning of not having the timer is for the game to not be over no matter how long it takes to complete a level. But that has some follow-on effects. If time doesn't matter, there's no reason to ever delay advancing to the next level, so that might as well be automatic (like it is if you let the timer run out), getting rid of the "Next Level" button. And there's no need to display the timer since it effectively doesn't exist.

On the other hand, maybe the player wants to disable the timer merely for a "practice mode" (requested in one of the forum posts mentioned last week), so they can pay attention to the timer but not have their run ruined if they go a little over. So I made "hide timer" and "enforce timer" separate settings. "Auto advance level" is also a separate setting, so the concept of "disabling the timer" is actually split into three separate settings.

Auto-advance with enforced timer#

Since those are separate settings, technically you could enable both "auto advance level" and "enforce timer", but that doesn't sound like a good way to play. One fix mentioned last week would be to rework the scoring when auto advance is enabled so you keep the leftover time when you advance past a level. A modification of that concept that would only affect the score and not the time would be that if you run out of time, retroactively adjust when some earlier level was ended, effectively spending the bonus points earned as time.

Autosave on level change#

I tried to implement the feature request for autosave at the end of each level, but I ran into the complication that if the game has already made the decision to move onto the next level (either due to an explicit press of the "Next Level" button or otherwise) then the save is necessarily at the start of the next level not the end of the level being completed. While a save at the beginning of each level mostly satisfies the request, one use of a save on advancing to the next level would be to adjust your plans to spend more time in the previous level preparing before going ahead.

The discussion above suggests a solution: if it's possible to go back and use your time from a previous level, then it autosaving at the start of the next level is effectively the same as at the end of the previous level. To fill out the possibilities, when not in "auto advance" mode, I could add a "Previous Level" button that would adjust the timer and bonus points like you had never clicked the "Next Level" button. It would only work if you were less far into the level than you had left on the timer when you clicked "Next Level", so it wouldn't change the game much.

This is a good example of having researched feature ideas having been helpful: the suggestion on scoring and the suggestion on autosave are non-obviously dependent on each other to form a coherent design.

Improving the display#

My initial reason for wanting to modify the Supply Challenge was playing it with its wiki page open on my second monitor to see what the future levels would request felt silly. The game could just tell me that information without needing to look it up.

The basic version of that was adding an option to duplicate the "next level" display for levels after the next level. For extra flexibility, I made it configurable to chose how many future levels to show information for (including "-1" meaning "all"). There's also an option to show the time until the end of each future level, so you can always know exactly how long you have left until you need to have those fast transport belts.

The other issue is that most items are requested in multiple levels, both meaning is not easy to see at a glance which items are new requests and it would be nice to know how many items will be needed in total for future levels and if those future requests have already been handled. So I added code to keep track of extra items in the supply chests that will be consumed on future levels and added an option to display how many more of a requested item will be requested in future levels, which uses that information to also display how many of those future requested items have already been supplied. In that mode, the future levels display is also more compact, only listing newly requested items. The next level display still shows all items, so you can see at a glance what requests remain for the next level.

Future work#

I would like to implement the autosave and scoring changes mentioned above. In addition, I think the making the mod not rely on the scenario and instead work in freeplay should hopefully be relatively straightforward. Then, instead of ending after the last level, it should just display your score and let you continue playing.

On the other hand, I don't have any plans for adding more levels (either set at the beginning or generated as you play), although I may look into what would be involved in defining a way for other mods to define challenges. Keeping in mind the "demands" ideas, I would want to make sure the API was flexible enough to handle "levels" being added after the game starts.

Another extension direction might be the train-focused variant suggested by this post. Maybe the request boxes should move? Maybe each request goes to a different box progressively further away? Could be awkward if you need to explore in the right direction to find the box, which could possibly be fixed by just telling the player where the next box is. I'm not sure how to balance this or if it would actually make for a fun variant, so I probably won't end up implementing it.

Comments

Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.

There are no comments yet.