Documentation last updated for mod loader version 7a+g (sorry for no css)

Making a Mod
MODS MUST USE THE FILE EXTENSION .json --- not .Json, .JSON, .JSOn, etc (will be fixed eventually... but seriously: You [probably] can't delete mods that use caps in file extension.)
Current Capabilities:
*add variants to building categories (such as a new painter type)
*variants define processing functions for shapes in/out
*translation support for variant names/descriptions

Notes:
*buildings in this early version must be in an already existing building category as a variant
*mod variants will be unlocked as soon as it's building category is unlocked (working on this)
*(mod) machines currently can't tell the game that they can't process a shape (such as if it can only accept circles) - only works for filtering shape vs color
*for now variants will use the speed upgrade that is expected for their building type
*underground belt variants can't define their own max lengths (yet)[assuming they work at all :)]

Coming Soon:
*custom levels for when variants become unlocked
*configs/settings for mods
*adding color mixes
*adding data to shapes (like how color is added)
*adding shapes
*map generation changes
*ez modpacks
*adding building categories


buildings you can add variants to:
Categories supported must be 1x1 dimensions Extra Notes
painter yes no
advanced_processor no
cutter yes no
energy_generator no
miner yes yes only building category that takes components.chainable component
mixer no
rotator yes yes
splitter yes no
stacker I think so no current must have the exact same components/slots as vanilla stacker
trash yes no doesn't allow for a speed to be displayed
underground_belt ? probably yes
belt no


Mods consist of a single .json file. The name of the file must be the same as your mod id. [example: mod_id.json]
For version 7a+g, mod jsons should define meta and variants properties. example:
{
  "meta": {"auth": "tiger", "id": "testmod", "modid": "tiger_testmod", "target": "7a+g", "version": 1},
  "variants": { ... }
}

auth: you, the author, meant to be unique (a-z,0-9 only pls)
id: the name of the mod (a-z,0-9 only pls)
modid: should be exactly identical to auth + "_" + id
target: the latest mod loader version you tested your mod with
version: rather arbitrary. The version of your mod (for organization or possible dependencies from other mods)

full mod json example:

Explaination of each field:
HalfPainter: A new variant (machine/building) added by your mod to the game (name it whatever you want, not just "HalfPainter")
  name: The id the game identifies your machine with
  Tnames: This defines the name of your machine as showed to players in-game. Default is what language is used if the player's language is not supported. Fields like "en" are for the name in that language.
  Tdescriptions: Similar to Tnames, except this is the description given.
  size: [How wide, and how tall] your machine will be in game. ie, miners are [1,1], painters are [2,1].
  speed: How fast your machine works - this get's boosted by upgrades. [1,6] is 1/6, meaning .166666666667, or once every 3 seconds
  category: The building category/tab for your machine to be listed under. See table above for possible values.
  image: A link (url or base 64 data:url) To the image you want to use for your building.
  bpimage: Similar to image but meant for use when showing as blueprint ghost.
  components: The logic of your machine.
    ItemAcceptor.slots: The positions of slots where items can come into your machine, and the direction they can enter that position (can be more than one direction). Filter is for whether that slot accpets shapes or colors.
    ItemEjector.slots: Where items are pushed out of the machine. Can only have one direction per slot.
    ItemProcessor: Where the magic happens. This is where you define what it is your machine does via JavaScript.
      inputsPerCharge: I don't actually know how this works. In a machine that has a shape slot and color slot, setting this to 2 makes the machine require one of each.
      func: A string containing the code that will be run for your machine. It uses the parameters "items" and "itemsBySlot" for input, and returns the output data.


example output:
using return [{layers:[[{subShape: 'rect', color: 'uncolored', requiredSlot: 0}, {subShape: 'circle', color: 'green'}, {subShape: 'star', color: 'red'}, {subShape: 'windmill', color: 'cyan'}], [{subShape: 'star', color: 'blue'}]]}]


using the slots "ItemAcceptor": {"slots": [{"pos": [0,0], "directions": ["left"], "filter": "shape"},{"pos": [1,0], "directions": ["top"], "filter": "color"}]}

inputs:
  items (order could be different): identical to itemsBySlot in this case.
  itemsBySlot: {"0":{"item":{"definition":{"layers":[[{"subShape":"rect","color":"uncolored"},{"subShape":"rect","color":"uncolored"},{"subShape":"rect","color":"uncolored"},{"subShape":"rect","color":"uncolored"}]],"cachedHash":"RuRuRuRu"}},"sourceSlot":0},"1":{"item":{"color":"green"},"sourceSlot":1}}


Tips:
Use null for empty corners when defining a layer.
Each item in the output goes to a slot, so to output a circle from one slot and a square from another, you would return a list with two values;