Page 1 of 3

[GUIDE] Level Creating and Modding

Posted: Tue Feb 12, 2013 5:37 pm
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.

Re: Guide for Level Creating and Modding

Posted: Tue Feb 12, 2013 8:03 pm
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? :)

Re: Guide for Level Creating and Modding

Posted: Tue Feb 12, 2013 8:24 pm
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 :)

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 9:25 am
by kovarex
I started writing some rough documentation of the scripting on wiki. (http://kovarex.com/wiki/index.php/Game_scripting)

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 12:19 pm
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?

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 12:26 pm
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.

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 12:53 pm
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 :)

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 2:02 pm
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 :)

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 2:06 pm
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

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 2:12 pm
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.

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 5:26 pm
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.

Re: Guide for Level Creating and Modding

Posted: Wed Feb 13, 2013 5:46 pm
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)

Re: Guide for Level Creating and Modding

Posted: Sat Feb 16, 2013 3:51 am
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.

Re: Guide for Level Creating and Modding

Posted: Sat Feb 16, 2013 4:36 am
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.

Re: Guide for Level Creating and Modding

Posted: Sat Feb 16, 2013 4:51 am
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]])

Re: Guide for Level Creating and Modding

Posted: Sat Feb 16, 2013 4:54 am
by slpwnd
Perfect example of what we mean by "The interface of the scripts will change" :)

Re: Guide for Level Creating and Modding

Posted: Thu Feb 21, 2013 3:36 pm
by NatLaTomate
The mods disapear when I upload a new version ? or Is there a file "mods" ?

Re: Guide for Level Creating and Modding

Posted: Thu Feb 21, 2013 4:05 pm
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.

Re: Guide for Level Creating and Modding

Posted: Thu Feb 21, 2013 5:00 pm
by NatLaTomate
Ok, thanks for the quick answer

Re: Guide for Level Creating and Modding

Posted: Sun Feb 24, 2013 11:57 am
by ficolas
The things in the wiki are really usefull, because reading the code is a bit boring :)