[GUIDE] Level Creating and Modding

Place to post guides, observations, things related to modding that are not mods themselves.
zlosynus
Global Moderator
Global Moderator
Posts: 114
Joined: Sat Feb 09, 2013 2:17 am
Contact:

[GUIDE] Level Creating and Modding

Post by zlosynus »

Hi,

this post should give some basic description how to create and/or modify levels and the game. This describes the current state in the game, and many things are very ligkely to be changed in future, so we cannot ensure any backwards compatibility.

There are two types of files which allow easy modifications:
  • .json files describe the game objects and their properties. For example the furnace object is described by this file:

    Code: Select all

      {
        "type": "furnace",
        "name": "stone-furnace",
        "flags": ["placeable-neutral", "player-creation"],
        "collision-box": [[-0.7, -0.7], [0.7, 0.7]],
        "selection-box": [[-0.8, -1], [0.8, 1]], 
        "minable": { "mining-time": 1, "result": "stone-furnace"},
        "max-health": 20,
        "source-inventory-size": 1,
        "result-inventory-size": 1,
        "burner":
        {    
          "heat-capacity": 100, 
          "heat-loss": 0.01,
          "heat-transport-speed": 0.005,
          "burning-speed": 0.001,
          "effectivity": 1000,
          "fuel-inventory-size": 1,
          "smoke":
          [    
            {    
              "name": "smoke",
              "frequency": 0.5, 
              "deviation": [0.1, 0.1],
              "position": [0, -2.3]
            }
          ]
        },
        "picture":
        {    
          "filename": "entity/stone-furnace/stone-furnace.png",
          "priority": "extra-high",
          "width": 96,
          "height": 96
        },
        "fire-animation":
        {
          "filename": "entity/stone-furnace/stone-furnace-fire.png",
          "priority": "extra-high",
          "frame-width": 18,
          "frame-height": 17,
          "frame-count": 16
        },
        "drawing-position": [0.35, -0.1],
        "fire-drawing-position": [-0.021875, 0.5234375],
        "drawing-scale": 0.7
      },   
    
    Using these files, you can modify recipes, and some behavior of the objects. It is limited mostly to simple modifications and changing numbers.
  • .lua files describe behavior of the level. You can script events such as attacks of enemies or starting position. There is an interface to the C++ code which allow you to call some functions of the game.

    For example, if you want to remove the creeper attacks in the 3rd demo level, you can just delete the following lines in the control.lua file:

    Code: Select all

    game.setmulticommand({type=defines.command.attack,
                              target=glob.player,
                              distraction=defines.distraction.byenemy},
                              glob.attackcount)
    
    And if you want to modify it in some existing save game, you can remove it from the control.lua file from the save game.
Long story short, for mods .json files are primary. To create and programs levels, you mostly use .lua files.
Last edited by rymn on Wed Mar 13, 2013 6:06 pm, edited 2 times in total.
Reason: made sticky, naming convention
User avatar
Narc
Filter Inserter
Filter Inserter
Posts: 279
Joined: Mon Feb 11, 2013 7:25 am
Contact:

Re: Guide for Level Creating and Modding

Post by Narc »

I'm really looking forward to knowing the current state of the scripting API -- like how to be notified when a player's building is created or destroyed, or how many of them are in the world. And what events exist and what they have in them. Reading the control.luas of the existing campaign levels has been exceptionally helpful.

...also, why does your game.oninit always have the comment "create a target chest"? Leftovers from an old version? :)
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

Narc wrote:...also, why does your game.oninit always have the comment "create a target chest"? Leftovers from an old version? :)
Exactly, the first testing script we used was to create cheating chest :)
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

I started writing some rough documentation of the scripting on wiki. (http://kovarex.com/wiki/index.php/Game_scripting)
User avatar
rk84
Filter Inserter
Filter Inserter
Posts: 556
Joined: Wed Feb 13, 2013 9:15 am
Contact:

Re: Guide for Level Creating and Modding

Post by rk84 »

kovarex wrote:I started writing some rough documentation of the scripting on wiki. (http://kovarex.com/wiki/index.php/Game_scripting)
Thats nice.

I'm editing demo's level 3. I made creepers to target steam engines and change distraction to anything. I would like to make the creeper wave size depend on number of steam engines. How I check the engine count?
Test mode
Searching Flashlight
[WIP]Fluid handling expansion
[WIP]PvP gamescript
[WIP]Rocket Express
Autofill: The torch has been pass to Nexela
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

rk84 wrote:I would like to make the creeper wave size depend on number of steam engines. How I check the engine count?
There is not very simple way to do that now.
You can keep track of the count steam engines by handling these events: onbuiltentity, onplayermineditem, onunitdied. when the name is steam-engine.

We will most probably add some native support of this later.
User avatar
rk84
Filter Inserter
Filter Inserter
Posts: 556
Joined: Wed Feb 13, 2013 9:15 am
Contact:

Re: Guide for Level Creating and Modding

Post by rk84 »

kovarex wrote: There is not very simple way to do that now.
You can keep track of the count steam engines by handling these events: onbuiltentity, onplayermineditem, onunitdied. when the name is steam-engine.

We will most probably add some native support of this later.
aa. Thank you.

My moddings are now on hold. I just downloaded alpha version :)
Test mode
Searching Flashlight
[WIP]Fluid handling expansion
[WIP]PvP gamescript
[WIP]Rocket Express
Autofill: The torch has been pass to Nexela
User avatar
mngrif
Fast Inserter
Fast Inserter
Posts: 173
Joined: Wed Feb 13, 2013 10:44 am
Contact:

Re: Guide for Level Creating and Modding

Post by mngrif »

I looked through demo level 2's control.lua hoping to find out how to generate cheaty chests, but that doesn't seem to be handled with lua. Being able to manipulate chest inventories would be a lot of fun, especially on a Feed The Beast style map where the goal is to make an insane amount of items as quickly as possible. In that style of map, you are constrained by key resources that is given to you in a rewards chest.

I want to make rewards chests, cheaty chests, and "magic" chests that do things to their contents :)
My Silly Factorian Tricks
<_aD> OBSERVE SIGNAL ASPECT BEFORE CROSSING TRACK
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

Valkor wrote:I looked through demo level 2's control.lua hoping to find out how to generate cheaty chests, but that doesn't seem to be handled with lua. Being able to manipulate chest inventories would be a lot of fun, especially on a Feed The Beast style map where the goal is to make an insane amount of items as quickly as possible. In that style of map, you are constrained by key resources that is given to you in a rewards chest.

I want to make rewards chests, cheaty chests, and "magic" chests that do things to their contents :)
It is possible, look here, you can use the function getinventory, to get access to the inventory object and work with that.
https://forums.factorio.com/wiki/index.php/Lua/Entity

Here is the example of our testing script we have been using during the developement:

Code: Select all


require "util"
require "defines"

-- create a target chest
game.oninit = function()
  glob.chest = game.createentity{name="steel-chest", position={x=13, y=3}}
  local chestinventory = glob.chest.getinventory(defines.inventory.chest)
  chestinventory.insert({name="iron-plate", count="256"})
  chestinventory.insert({name="copper-plate", count="128"})
  chestinventory.insert({name="steel-plate", count="128"})
  chestinventory.insert({name="basic-transport-belt", count="64"})
  chestinventory.insert({name="fast-transport-belt", count="128"})
  chestinventory.insert({name="express-transport-belt", count="128"})
  chestinventory.insert({name="basic-mining-drill", count="128"})
  chestinventory.insert({name="gun-turret", count="64"})
  chestinventory.insert({name="rocket-turret", count="64"})
  chestinventory.insert({name="basic-inserter", count="64"})
  chestinventory.insert({name="fast-inserter", count="64"})
  chestinventory.insert({name="long-handed-inserter", count="64"})
  chestinventory.insert({name="filter-inserter", count="64"})
  chestinventory.insert({name="smart-inserter", count="64"})
  chestinventory.insert({name="iron-gear-wheel", count="64"})
  chestinventory.insert({name="steam-engine", count="8"})
  chestinventory.insert({name="small-electric-pole", count="32"})
  chestinventory.insert({name="wood", count="64"})
  chestinventory.insert({name="coal", count="128"})
  chestinventory.insert({name="car", count="1"})
  chestinventory.insert({name="pipe", count="64"})
  chestinventory.insert({name="iron-axe", count="10"})
  chestinventory.insert({name="pistol", count="1"})
  chestinventory.insert({name="rocket-launcher", count="1"})
  chestinventory.insert({name="basic-bullet-magazine", count="100"})
  chestinventory.insert({name="piercing-bullet-magazine", count="100"})
  chestinventory.insert({name="rocket", count="100"})
  chestinventory.insert({name="stone", count="128"})
  chestinventory.insert({name="stone-furnace", count="64"})
  chestinventory.insert({name="electronic-circuit", count="256"})
end
User avatar
mngrif
Fast Inserter
Fast Inserter
Posts: 173
Joined: Wed Feb 13, 2013 10:44 am
Contact:

Re: Guide for Level Creating and Modding

Post by mngrif »

kovarex wrote: Here is the example of our testing script we have been using during the developement:
At long last, we have the rest of the "create a target chest"! Thank you, this will greatly accelerate me once my key arrives.

"Entity is everything on the map except tiles." Good to know. Time to give the wiki a read.

Edit:
Where does the player spawn? 0, 0? A player.getCoordinates would be useful.
My Silly Factorian Tricks
<_aD> OBSERVE SIGNAL ASPECT BEFORE CROSSING TRACK
User avatar
Narc
Filter Inserter
Filter Inserter
Posts: 279
Joined: Mon Feb 11, 2013 7:25 am
Contact:

Re: Guide for Level Creating and Modding

Post by Narc »

Well, the player *is* an entity, it does have coordinates:

Code: Select all

var thePlayer = game.getPlayer()
-- thePlayer is at thePlayer.position.x by thePlayer.position.y
I haven't played with Lua in a while, but that should be in the right ballpark.
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

Narc wrote:Well, the player *is* an entity, it does have coordinates:

Code: Select all

var thePlayer = game.getPlayer()
-- thePlayer is at thePlayer.position.x by thePlayer.position.y
I haven't played with Lua in a while, but that should be in the right ballpark.
Yes, as it is written on the wiki, player is extension of Entity (you can imagine it as if the luaPlayer was inherited from luaEntity, if you like oop)
User avatar
Polymorph
Burner Inserter
Burner Inserter
Posts: 9
Joined: Wed Feb 13, 2013 2:24 am
Contact:

Re: Guide for Level Creating and Modding

Post by Polymorph »

While printing all of the functions in game I noticed one that would be useful in some of my experiments: findentities. It takes a table which I presume is either an entity to search for or perhaps search filters, but I don't know what keys or values I would need to put in it. Any information would be useful. Basically I'm trying to get every entity of a certain type, regardless of distance. There's also getentitybytag, but I'm not sure if it gets more than one entity.
slpwnd
Factorio Staff
Factorio Staff
Posts: 1835
Joined: Sun Feb 03, 2013 2:51 pm
Contact:

Re: Guide for Level Creating and Modding

Post by slpwnd »

Polymorph wrote:While printing all of the functions in game I noticed one that would be useful in some of my experiments: findentities.
Function findentities takes a single argument - a table representing the bounding box where to search for the entities. The table must have a "topleft" and "bottomright" keys which are both tables representing the position. That means that they both have keys "x", "y" for the real position (starting from 0, 0 point).

Example from the demo/level-01/control.lua:

Code: Select all

local entities = game.findentities{topleft = {x = event.createdentity.position.x - 1,
                                              y = event.createdentity.position.y - 1},
                                   bottomright = {x = event.createdentity.position.x + 1,
                                                  y = event.createdentity.position.y + 1}}
As for the getentitybytag:
There's also getentitybytag, but I'm not sure if it gets more than one entity
The tagging mechanism is used for connecting the objects created in the map editor with the logic in the script. Pressing T while having a selected entity in the map editor opens a small gui where you can insert a tag (must be unique per map) for the entity. You can then get the entity by the tag name in the lua script. Function getentitybytag takes a single argument (tag string) and returns a single object representing the entity or nil. I believe we have used this one in the second level of the demo for tagging the two inserters built from the start.

Hope this helps.
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

slpwnd wrote:
Polymorph wrote:

Code: Select all

local entities = game.findentities{topleft = {x = event.createdentity.position.x - 1,
                                              y = event.createdentity.position.y - 1},
                                   bottomright = {x = event.createdentity.position.x + 1,
                                                  y = event.createdentity.position.y + 1}}
I would prefer to have this alternative in the future, we define bounding boxes this way in the json files.

Code: Select all

local entities = game.findentities([[event.createdentity.position.x - 1, event.createdentity.position.y - 1],
                                    [event.createdentity.position.x + 1, event.createdentity.position.y + 1]])
slpwnd
Factorio Staff
Factorio Staff
Posts: 1835
Joined: Sun Feb 03, 2013 2:51 pm
Contact:

Re: Guide for Level Creating and Modding

Post by slpwnd »

Perfect example of what we mean by "The interface of the scripts will change" :)
NatLaTomate
Burner Inserter
Burner Inserter
Posts: 12
Joined: Fri Feb 08, 2013 3:16 pm
Contact:

Re: Guide for Level Creating and Modding

Post by NatLaTomate »

The mods disapear when I upload a new version ? or Is there a file "mods" ?
kovarex
Factorio Staff
Factorio Staff
Posts: 8207
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: Guide for Level Creating and Modding

Post by kovarex »

The uninstaller uninstalls just files that it installed, so it shouldn't disappear (If the mod contains just new files, no modificaiton of existing ones).

I can't guarantee that in the future, but keep in mind, that we plan to do native mod support in the future, and all this will be taken care of well.
The plan is, that people will never touch the original game data (so auto updater works correctly, as it will contain only the binary delta of all files, we don't want people to download the whole game on every update), and all mods will be separate folders, it will be either additional files or/and lua scripts specifating modification of the original files)
This way even several mods modifying different atributies of the same object will work.
NatLaTomate
Burner Inserter
Burner Inserter
Posts: 12
Joined: Fri Feb 08, 2013 3:16 pm
Contact:

Re: Guide for Level Creating and Modding

Post by NatLaTomate »

Ok, thanks for the quick answer
ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

Re: Guide for Level Creating and Modding

Post by ficolas »

The things in the wiki are really usefull, because reading the code is a bit boring :)
Post Reply

Return to “Modding discussion”