Fusion reactor help?

Place to get help with not working mods / modding interface.
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Fusion reactor help?

Post by Inzann »

I cannot figure out what type to use for the entity.lua. I tried having the type as generator but it just crashed my game. I think it mentioned something about a fluid (I guess water). So for now I have been using solar panel but this only works when the sun is up, any ideas?

Code: Select all

data:extend(
{
	{
		type = "solar-panel", --THIS is the part I cannot figure out what to use.
		name = "fusion-reactor-mk1",
		icon = "__PajMod__/graphics/icons/fusion-reactor-mk1.png",
		flags = {"placeable-neutral", "player-creation"},
		minable = {hardness = 0.2, mining_time = 0.5, result = "fusion-reactor-mk1"},
		max_health = 150,
		corpse = "big-remnants",
		collision_box = {{-1.4, -1.4}, {1.4, 1.4}},
		selection_box = {{-1.5, -1.5}, {1.5, 1.5}},
		picture = {
			filename = "__PajMod__/graphics/entity/fusion-reactors/fusion-reactor-mk1.png",
			priority = "high",
			width = 110,
			height = 110
		},
		energy_source = {
			type = "electric",
			usage_priority = "primary-output"
		},
		production = "1MW"
	}
})
User avatar
darius456
Fast Inserter
Fast Inserter
Posts: 222
Joined: Thu Jan 02, 2014 6:33 am
Contact:

Re: Fusion reactor help?

Post by darius456 »

I think that solar panel might be ok for your purposes... try to work with entity.energy.
I assume that when night come energy of solar panel slowly decreases and finally reach 0 J.
So i thing that you should monitor the day time or monitor the entity.energy and when it drop from max try to entity.energy = max_energy
entity - it is solar panel

Code: Select all

any_variable = game.createentity{name = "your device name", position= {pos_x, pos_y}, force=game.forces.player}
current_energy = any_variable.energy
any_variable.energy = number
any_variable - it is a pointer to entity... it is table... any_variable.position any_variable.energy any_variable.name ...... etc.

This is example how to use entity.energy. Energy behavior is very unpredictable. I tried to figure it out modding the inserter but no luck. But i thing that in you case it should work.
Lenovo Y580 8GB Ram GF660m 128GB SSD W7
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

darius456 wrote:I think that solar panel might be ok for your purposes... try to work with entity.energy.
I assume that when night come energy of solar panel slowly decreases and finally reach 0 J.
So i thing that you should monitor the day time or monitor the entity.energy and when it drop from max try to entity.energy = max_energy
entity - it is solar panel

Code: Select all

any_variable = game.createentity{name = "your device name", position= {pos_x, pos_y}, force=game.forces.player}
current_energy = any_variable.energy
any_variable.energy = number
any_variable - it is a pointer to entity... it is table... any_variable.position any_variable.energy any_variable.name ...... etc.

This is example how to use entity.energy. Energy behavior is very unpredictable. I tried to figure it out modding the inserter but no luck. But i thing that in you case it should work.
I am very new at modding so I don't really understand what you are saying or how to apply this to my code. But you say I should make my own entity? This seems much more complicated then I first thought. :/

My plan was just to make a fusion reactor that requires nothing to run (it will run 24/7) but at the cost of being expensive to craft. Is it necessary for me to go this far for something that sounds so simple? :P
User avatar
darius456
Fast Inserter
Fast Inserter
Posts: 222
Joined: Thu Jan 02, 2014 6:33 am
Contact:

Re: Fusion reactor help?

Post by darius456 »

Inzann wrote: I am very new at modding so I don't really understand what you are saying or how to apply this to my code. But you say I should make my own entity? This seems much more complicated then I first thought. :/

My plan was just to make a fusion reactor that requires nothing to run (it will run 24/7) but at the cost of being expensive to craft. Is it necessary for me to go this far for something that sounds so simple? :P
I understand but you allready created new entity. It is fusion reactor it's type is solar panel but name fusion reactor. All you have to do is to tell your reactor that day is all the time. I think that the only way is to monitor and chanege if necessary the entity.energy. The entity.energy should be greater than 0 to produce electricity. I don't know if it will work but I think it should.

You have to write some code in control.lua

Read this: link
Lenovo Y580 8GB Ram GF660m 128GB SSD W7
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

darius456 wrote: I understand but you allready created new entity. It is fusion reactor it's type is solar panel but name fusion reactor. All you have to do is to tell your reactor that day is all the time. I think that the only way is to monitor and chanege if necessary the entity.energy. The entity.energy should be greater than 0 to produce electricity. I don't know if it will work but I think it should.

You have to write some code in control.lua

Read this: link
Ok, so I must fool it into thinking its day all the time and do this in control.lua but I don't understand the use of "entity.energy". I read the link you sent and understood the first part until he got into the control.lua part. Thats where it got more complicated. Is it possible for you to show me the code that would work for me and explain the specific bits and what its purposes are?
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

Inzann wrote: I read the link you sent and understood the first part until he got into the control.lua part. Thats where it got more complicated.
Sorry about that, I did try my best to simplify it but it is 'free' programming (and programming takes some time and effort to learn if you are new to it) whereas the prototypes are very specific in what must be included (and there are several examples in the base game) and anything that the game doesn't know how to handle is ignored (or causes an error).

I'm not sure what your generator code was so I can't say for sure why it caused an error with the liquid (but the generator entity type requires a liquid to run off of). As for the solar panel it is hard coded to decrease to 0 at night (a shame there isn't an option to specify the time(s) that it runs but alas there is not), and there is no function to make it ignore the time either, but you can 'take control' at night and force it to have power. That is what entity.energy is being used for ('entity' is a generic variable name and 'energy' is the energy buffer of the entity).
side note: you can make it always day using the console (or control.lua) and typing "game.alwaysday = true" (without quotes), but that's not quite the same thing as making it run at night :)

To take control like that you'd need a control.lua similar to the code below, it's heavily commented (and some comments are long so you might want to copy/paste into your text editor to improve the readability :)). Also note, there is a short summary of the code below it:

Code: Select all

require "defines"
game.oninit( -- when a new game is started run the following function
  function() -- start of an anonymous (aka unnamed) function
    glob.fusionReactors = {} -- make an empty table called fusionReactors within the table 'glob' (glob is the only table that is loaded with save games)
  end -- end anonymous function
) -- end oninit function call

game.onload( -- when a save file is loaded
  function()
    if not glob.fusionReactors then -- if the fusionReactors table does not exist when a save is loaded (because the mod was added after the world was started)
      glob.fusionReactors = {} -- create it.
    end -- end if statement
  end
) -- end onload function call

game.onevent( -- generic onevent call (used for all events except oninit, onload, and onsave)
  --V the identifier of the actual event that we are defining a function for. They are in an 'event' table that is in the defines table (created by requiring defines), see either the wiki or Factorio\data\core\lualib\defines.lua for the full listing (and a few other defined identifiers)
  defines.event.onentitybuilt, -- is raised/signaled when the player builds any entity.
  function(event) -- function to be run, this time it is being passed a variable called 'event' which is a table of the event information
    if event.createdentity.name == "your_fusion_reactors_name" then -- if the created entity's name is that of your fusion reactor
      table.insert(glob.fusionReactors, event.createdentity) -- insert a reference to the new reactor into the glob.fusionReactors table, for use in ontick below
    end -- end if
  end -- end anon function
) -- end onevent call

game.onevent(defines.event.ontick, function(event) -- call to onevent with id for ontick event (which normally runs 60 times / second), and anon-function
  -- limit the following code to running once per second to avoid possible lag, AND
  -- only if the darkness level is over 50% (play with these if you need to, especially the darkness level)
  if (event.tick % 60 == 0) and (game.darkness > 0.5) then
     -- loop through the glob.fusionReactors table assigning the index of each reactor to the variable 'index', 
    -- and the value (which is a reference to the reactor) to the variable 'reactor'
    for index, reactor in ipairs(glob.fusionReactors) do
      if not reactor.valid then -- if the reactor is not valid (because it was mined or destroyed)
        table.remove(glob.fusionReactors, index) -- remove it from the table so we don't have to skip it every time and to avoid crashes
      else -- otherwise if the reactor IS valid
        reactor.energy = 1000000000 -- set the reactor's buffer to some large value (it'll be limited to the buffer's max size anyways so don't worry)
      end
    end
  end
end) -- end both anon-function and onevent call on the same line.
The above code creates a table called fusionReactors within the glob table when a new game is started and if it doesn't exist when a save is loaded (it's in the glob so that the data stored in it persists, aka stays there, between saving closing and reopening Factorio). Then it monitors when the player builds an entity and when they do, if the built entity was a fusion reactor it adds a reference to that entity into the fusionReactors' table for use in ontick. In ontick (which is an event that happens 60 times per second, assuming the game.speed is 1 which it probably is) it uses an if statement to prevent the anon-function code from running more than once a second (event.tick % 60) and only when the darkness level is greater than 50% (game.darkness > 0.5), when it's both 'dark' and it's been more than a second since the function last ran it will then loop through the fusionReactors' table. The loop first checks if the reactors are no longer valid (from being mined or destroyed) and if so removes them from the table, otherwise (if they are still valid) it fills the reactor's buffer (seemingly, in-game anyways, tricking the reactor into generating energy).

I hope you find that at least a bit more helpful! :D
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

I tried using the code you provided and understanding it, I understand some of it but not all, anyways when I try to implement it in control.lua I get this error seen below. What does it mean? I have so many mod ideas I want for this game but I am just too noob to make any of them happened. :(

control.lua:19: attempt to index field 'event' (a nil value)

Code: Select all

    game.onevent( -- generic onevent call (used for all events except oninit, onload, and onsave)
      --V the identifier of the actual event that we are defining a function for. They are in an 'event' table that is in the defines table (created by requiring defines), see either the wiki or Factorio\data\core\lualib\defines.lua for the full listing (and a few other defined identifiers)
      defines.event.onentitybuilt, -- is raised/signaled when the player builds any entity. -- THIS IS ROW 19
      function(event) -- function to be run, this time it is being passed a variable called 'event' which is a table of the event information
        if event.createdentity.name == "fusion-reactor-mk2" then -- if the created entity's name is that of your fusion reactor
          table.insert(glob.fusionReactors, event.createdentity) -- insert a reference to the new reactor into the glob.fusionReactors table, for use in ontick below
        end -- end if
      end -- end anon function
    ) -- end onevent call
User avatar
rk84
Filter Inserter
Filter Inserter
Posts: 556
Joined: Wed Feb 13, 2013 9:15 am
Contact:

Re: Fusion reactor help?

Post by rk84 »

couple typos

Code: Select all

defines.events.onbuiltentity,
Test mode
Searching Flashlight
[WIP]Fluid handling expansion
[WIP]PvP gamescript
[WIP]Rocket Express
Autofill: The torch has been pass to Nexela
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

rk84 wrote:couple typos
you beat me to it :)

yeah, 'event' should be 'events' on line 19. and 'onentitybuilt' should be 'onbuiltentity'...(I make that mistake relatively often just because it makes more sense to me) sorry. Both of those are discovered by looking in the defines.lua file (data\core\lualib\defines.lua) or on the wiki page Lua/Events

edit (wanted to get the why posted first): now as to what the error meant, when you access (aka index) a table, like defines, then you get back a value. If what you indexed existed then you get what is stored in the table for that index, but if it does not exist you get back the value of 'nil' which is essentially 'no value' (or 'void' or 'null' if those mean anything to you). So when you try to get the proper id for onbuiltentity (assuming of course that it'd been spelled right...) what actually happened is that you are (logically) going to the defines table and asking for the value of "event" (which should be "events"), well the table does not have a value for the index of "event" and so it gives you the value 'nil'. Then lua sees that you still have more of the command left so it rewrites it as, nil.onbuiltentity ..., the problem is that nil has no value and you can only index a table, so when lua tries to get "onbuiltentity" it sees that you are trying to index a nil value and (since only a table can store and give access to multiple values inside of it) throws an error about 'trying to index a nil value'.
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

FreeER wrote:
rk84 wrote:couple typos
you beat me to it :)

yeah, 'event' should be 'events' on line 19. and 'onentitybuilt' should be 'onbuiltentity'...(I make that mistake relatively often just because it makes more sense to me) sorry. Both of those are discovered by looking in the defines.lua file (data\core\lualib\defines.lua) or on the wiki page Lua/Events

edit (wanted to get the why posted first): now as to what the error meant, when you access (aka index) a table, like defines, then you get back a value. If what you indexed existed then you get what is stored in the table for that index, but if it does not exist you get back the value of 'nil' which is essentially 'no value' (or 'void' or 'null' if those mean anything to you). So when you try to get the proper id for onbuiltentity (assuming of course that it'd been spelled right...) what actually happened is that you are (logically) going to the defines table and asking for the value of "event" (which should be "events"), well the table does not have a value for the index of "event" and so it gives you the value 'nil'. Then lua sees that you still have more of the command left so it rewrites it as, nil.onbuiltentity ..., the problem is that nil has no value and you can only index a table, so when lua tries to get "onbuiltentity" it sees that you are trying to index a nil value and (since only a table can store and give access to multiple values inside of it) throws an error about 'trying to index a nil value'.
Ok I think I understand the reason behind the error now, but again I have pretty much the same error (I think).
control.lua:22 bad argument #1 to 'insert' (table expected, got nil).

The entire code section. The way I understand it only the defines.event had to be change to events. The rest of the code using "event" is just random variable naming? Once again I don't understand what this error means. glob.fusionReactors table was created in the section above so why does it expect table again? :p

Code: Select all

require "defines"

    game.oninit( -- when a new game is started run the following function
      function() -- start of an anonymous (aka unnamed) function
        glob.fusionReactors = {} -- make an empty table called fusionReactors within the table 'glob' (glob is the only table that is loaded with save games)
      end -- end anonymous function
    ) -- end oninit function call

    game.onload( -- when a save file is loaded
      function()
        if not glob.fusionReactors then -- if the fusionReactors table does not exist when a save is loaded (because the mod was added after the world was started)
          glob.fusionReactors = {} -- create it.
        end -- end if statement
      end
    ) -- end onload function call

    game.onevent( -- generic onevent call (used for all events except oninit, onload, and onsave)
      --V the identifier of the actual event that we are defining a function for. They are in an 'event' table that is in the defines table (created by requiring defines), see either the wiki or Factorio\data\core\lualib\defines.lua for the full listing (and a few other defined identifiers)
      defines.events.onbuiltentity, -- is raised/signaled when the player builds any entity.
      function(event) -- function to be run, this time it is being passed a variable called 'event' which is a table of the event information
        if event.createdentity.name == "fusion-reactor-mk2" then -- if the created entity's name is that of your fusion reactor
          table.insert(glob.fusionReactors, event.createdentity) -- insert a reference to the new reactor into the glob.fusionReactors table, for use in ontick below ROW __22__
        end -- end if
      end -- end anon function
    ) -- end onevent call

    game.onevent(defines.events.ontick, function(event) -- call to onevent with id for ontick event (which normally runs 60 times / second), and anon-function
      -- limit the following code to running once per second to avoid possible lag, AND
      -- only if the darkness level is over 50% (play with these if you need to, especially the darkness level)
      if (event.tick % 60 == 0) and (game.darkness > 0.5) then
         -- loop through the glob.fusionReactors table assigning the index of each reactor to the variable 'index',
        -- and the value (which is a reference to the reactor) to the variable 'reactor'
        for index, reactor in ipairs(glob.fusionReactors) do
          if not reactor.valid then -- if the reactor is not valid (because it was mined or destroyed)
            table.remove(glob.fusionReactors, index) -- remove it from the table so we don't have to skip it every time and to avoid crashes
          else -- otherwise if the reactor IS valid
            reactor.energy = 1000000000 -- set the reactor's buffer to some large value (it'll be limited to the buffer's max size anyways so don't worry)
          end
        end
      end
    end)
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

Inzann wrote:The way I understand it only the defines.event had to be change to events. The rest of the code using "event" is just random variable naming?
Yeah, not 'random' but 'arbitrary', the difference is that arbitrary has some reason whereas random is just picking anything. The reason to use 'event' as the variable inside onevent is because it matches what you expect (event data).
Inzann wrote:Once again I don't understand what this error means. glob.fusionReactors table was created in the section above? :p
hm...I'm not sure why it's saying the fusionReactors table is nil, since yes, it should have been created either when the game was started (via oninit) or when the save was loaded if it didn't exist (via onload)... hm, could you upload the full mod for testing purposes?
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

I'm not getting any errors with what you uploaded...either with a new game or with a loaded save created prior to installing the mod.
just a note that shouldn't matter, I'm using Factorio version 0.9.8, and I only assume that you are as well :)

I encountered this only once (someone uploaded a non-working file and the uploaded file worked) and it was 'magically' resolved by overwriting the control.lua with an exact copy of itself....
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

Ah I think it was conflicting with another code I had in my control.lua. I removed it and I could place the reactor down, however it didn't generate any power at night. Since it gives no errors I'm not really sure what to start looking at? :roll:
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

Inzann wrote:I removed it and I could place the reactor down
ok good. Now, if it's giving no power at night you'd look at the game.darkness > 0.5 line and try to decrease the 0.5 so that it gives power sooner.

it's also possible you'd need to actually run it more than once every 60 ticks (1 second) so that it gives power more often...but those are the two values you'd need to try decreasing at this point :) Internally (c++) power is given every tick, but it's best to start with every second in lua because you can easily create a lot of lag if you do too much every tick (lua is inherently slower than the C++ code because it's not compiled to machine code prior to being executed and it relies upon interacting with the C++ code, which, of course, adds a bit of delay when passing data back and forth).
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

Ah alright thank you, just a question as I test this. Does my saved game automaticly retrieve any new code changes from the mod as soon as I load the game? I know I had some troubles getting my saved game to load in changed recipes for an item, I had load an earlier save and research the technology again to make it work. Any idea what I could do about this?

Edit:
I tried these combinations and none of them worked for me.
First one every 1 second if darkness > 50% (I think?) it should then feed energy, but it doesn't.
Second one every 0.5 second if darkness > 10% it should feed energy. Doesn't work either. XD
if (event.tick % 60 == 0) and (game.darkness > 0.5) then
if (event.tick % 30 == 0) and (game.darkness > 0.1) then
if (event.tick % 10 == 0) and (game.darkness > 0.9) then

Also another question while I'm still able to edit this post, what unit is the reactor.energy value in?
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

The control.lua for mods are not copied to the save file so yes, when loading a save the most recent versions of the code is used (without needing to run any commands to update it).
The prototypes are saved with the save file (within level.dat, for detecting when prototypes that are in the save no longer exist in the mod..which could cause errors lol) so they require an explicit command to update them

just a note: the freeplay control.lua is also saved but it's rarely modified (so if you for some reason wanted to change it after starting a game you'd have to manually open the copied control.lua from the save file and edit it). Hope that makes it clear :)
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

Inzann wrote:Also another question while I'm still able to edit this post, what unit is the reactor.energy value in?
I'm fairly sure that it's an unsigned integer value. You can print it out before and after setting it with game.player.print(reactor.energy) to see the values (and you can do so via the console as well, though you'll need to hover your cursor over it and use game.player.print(game.player.character.selected.energy) since you can not 'see' the reactor variable from the console).
Inzann
Inserter
Inserter
Posts: 33
Joined: Fri May 02, 2014 9:10 pm
Contact:

Re: Fusion reactor help?

Post by Inzann »

Alright that explains some of my question but I still don't know why my changed values have no effect on the game. Does it work when you test?
User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: Fusion reactor help?

Post by FreeER »

Inzann wrote:Alright that explains some of my question but I still don't know why my changed values have no effect on the game. Does it work when you test?
I have this for testing

Code: Select all

game.onevent(defines.events.ontick, function(event)
  if game.darkness > 0.1 then
    for index, reactor in ipairs(glob.fusionReactors) do
      if not reactor.valid then
        table.remove(glob.fusionReactors, index)
      else
        game.player.print(reactor.energy)
        reactor.energy = 1000000000
        game.player.print(reactor.energy)
     ...
and it's working (it doesn't show the power on the reactor, but it does provide the power as seen by right clicking a power pole, assuming that there are machines drawing the power). note that the above code is running every tick because I removed the game.tick % condition
Post Reply

Return to “Modding help”