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#

Read more…

Devlog: Supply Challenge Plus (1 of 2): requirements gathering

The problem#

Factorio comes with a scenario called Supply Challenge which is a shorter, more directed experience than the standard "Freeplay" game mode. It replaces the pressure from enemies attacking your base with a series of timed requests where you have to provided a pre-defined set of items within a time limit with a new request every several minutes. This both can be good for new players to have guidance on what they should be working on next and for experienced players as getting everything done within the time limit can be, as the name suggests, a challenge. As those are two somewhat opposing goals, I wanted to add settings to make it better for both use cases.

But first was the question that precedes many coding projects: has someone already done this?1 And the related question: has anyone suggested doing it and what features did they find important that might be worth considering in the design?

Why?#

For a personal project that possibly no one else is going to use, it's not immediately obvious why I care what features other people might want. But there's a few reasons such a search can be valuable in addition to the obvious that other people might use what I create. First, finding other users wanting the same features I want is validation that those features are good ideas. Other people may have thought of features that I hadn't thought to implement but actually want. And even for features that I am not interested in implementing at the moment, keeping them in mind may affect the design.

Initial ideas#

Read more…

Metatables for Factorio reflection mod

The problem#

Using my Factorio reflection library discussed previously involves interacting with Lua values that are a combination of the actual value and some metadata, so you have to know about those values to use them. Worse, the interactions I defined are quite verbose. The main thing you're like to want to do on a value is lookup a property on it. Normally in Lua that looks like

table[key]

but if instead of table you have a wrapped value from the reflection library, you would look up key on it with

ReflectionLibraryMod.typed_object_lookup_property(
    wrapped, key).value

If you want to do multiple levels of property lookups, then this quickly gets quite unwieldy.

The solution#

Lua supports operator overloading through a mechanism it calls metatables (some additional examples).

Using that mechanism, the library defines a value ReflectionLibraryMod.typed_data_raw that can be indexed as wrapped[key] and assigned to like wrapped[key] = newValue.

The basic setup looks like

local prototype = {} -- table for methods
local mt = {}
mt.__index = function (table, key)
  local res = prototype[key]
    or ReflectionLibraryMod.wrap_typed_object(
      ReflectionLibraryMod.typed_object_lookup_property(
        table._private, key))
  if res == nil then
    if key == "_value" then
      res = table._private.value
    end
  end
  return res
end

mt.__newindex = function (table, key, newValue)
  -- If newValue is a wrapped typed value, then unwrap it.
  if getmetatable(newValue) == mt then
    newValue = newValue._private.value
  end
  table._private.value[key] = newValue
end

function ReflectionLibraryMod.wrap_typed_object(typedValue)
  if typedValue == nil then
    return nil
  end

  local res = {_private = typedValue}
  setmetatable(res, mt)

  return res
end

Any additional properties would be defined next to the definition of _value. And any methods would be defined on prototype.

The details#

Read more…

Devlog: Factorio reflection mod

The problem#

When developing the "garbage collector" for the Pacifist mod, I noted that I couldn't actually know which strings should be treated as references. As a workaround, I just assumed all strings were references, which worked well enough, but I wondered if there was a way to get more precise type information. Additionally, when I was trying to figure this out, the developer of exfret's randomizer expressed interest in getting access to such information for that mod.

The solution#

The Factorio documentation includes a machine-readable version of the prototype API documentation. My ReflectionLibrary mod provides access to that information from within a Factorio mod, effectively faking a reflection API for type information on data.raw during the Prototype Stage:

local data_raw = ReflectionLibraryMod.typed_data_raw

local bb = data_raw['blueprint-book']['blueprint-book']
log(bb.inventory_size._type.typeKind)  # prints "literal"
bb.inventory_size = 42
log(bb.inventory_size._type.typeKind)  # prints "alias"
log(bb.inventory_size._type.name)   # prints "ItemStackIndex"

The details#

Read more…

Devlog: Pacifist Factorio mod PRs (3 of 3): garbage collection

The problem#

Continuing from the past two weeks, in my work on the Pacifist Factorio mod, I noticed there were rich text icons for military-related entities that I thought the mod had removed from the game. By "rich text icons", I'm referring to the dialog that some text boxes in the game (e.g. for naming a train stop) have a button to bring up which shows icons that can be inserted into the text box which include all of the items in the game along with a few other things. In that dialog, there were icons for things like biter corpses despite biters having been removed from the game.

The solution#

This PR, which is included in the latest version of Pacifist, hides all of the icons related only to items that have been removed or hidden by Pacifist.

The details#

Read more…

Devlog: Pacifist Factorio mod PRs (2 of 3): butter slots, not gun slots

The problem#

Continuing from last week, in my work on the Pacifist Factorio mod, I wanted to remove the character's gun slots. They are always visible in the bottom-left of the screen with gun and ammo icons, making it clear there's an expectation of weapons.

The solution#

This PR, which is included in the latest version of Pacifist, replaces the icon on the slots and rewords some of the text shown in the game about them.

The details#

Read more…

Devlog: Pacifist Factorio mod PRs (1 of 3): strings, strings, strings

The problem#

I wanted to introduce Factorio to some younger cousins but didn't think the military aspects of the game would be appropriate for them, both because their parents would rather they not be playing violent video games and it's simply an additional distraction and added complexity in a game that's already fairly involved, especially for a child.

Due to Factorio's active modding community, often if you can think of a mod you want, someone else has already thought of it and implemented it. And it turned out I'm not the first person to a less violent Factorio: Pacifist already existed and did most of what I wanted. Like many Factorio mods, it's open-source and has a GitHub page. The developer was very friendly and helpful, so I was able to contribute changes get them into the next release of the mod.

My contributions weren't fixing bugs in the mod as much as nudging its goals in a slightly different direction: it was already removing the military aspect from the gameplay, but I also wanted to remove hints of it from the UI as much as possible.

The solution#

Play Factorio with Pacifist, which now includes my changes. I recommend also including my mod BackpackRename. Additionally, I found the StartAlt and Attention Indicator mods good for playing with new players.

The details#

Read more…

Devlog: Anagram Bagels: Part 2

There were two non-trivial aspects of the design of Anagram Bagels: puzzle generation, which I discussed in my last post, and how to handle saving and sharing puzzles, which I will discuss in this post. I wanted an intuitive design that satisfied the following constraints:

  1. It should be possible to easily share a puzzle with another person in the form of a link.

  2. The difference between a link to the game and a link to a specific puzzle should be clear. (So the user doesn't accidentally bookmark a link to a specific puzzle when meaning to bookmark the game.)

  3. The game should gracefully handle the common mobile browser behavior of reloading the page if it hasn't been viewed in a while.

  4. Opening multiple instances of the game in separate tabs shouldn't break anything. (This is the default for web sites, so it's true unless doing something to actively break this assumption.)

Read more…

Devlog: Anagram Bagels: Part 1

Introduction#

I have a friend who plays a lot of simple puzzle games on their phone. One of them is this word puzzle, which is variant of Bagels (also known as Bulls and Cows or by the trademarked name Mastermind) where the secret is an English word and the guesses must be valid words. Additionally, the alphabet of the guesses is limited to a set selected for the puzzle, and the feedback is given for specific letters as opposed to giving just a count of the correct letters.

While playing the game, my friend would often find that it would be useful to type letters out of order. For example, once determing that the word ends in "ing", it would be easier to simply write that in at the end and then fill out the beginning. As the feedback means the player often knows exactly what they want to write in the middle of the word, typing each word in order from the start to end can be awkward.

As the game seems quite simple, I decided to reimplement it and improve upon the UI. My implementation is in HTML5/JavaScript and should work in any modern browser. Play Anagram Bagels or view the source.

Read more…