Page 1 of 1

[Modpack] Wireworld Mod

PostPosted: Tue Apr 14, 2015 02:03
by Byakuren
I read this: https://unnikked.ga/simulate-logic-circuits-wireworld

and decided it might be neat to implement in minetest.

This is my first mod other than the tutorial one on the wiki, so any pointers are appreciated.

Repo: https://github.com/raymoo/minetest-wireworld

Latest Release (0.0.4):
https://github.com/raymoo/minetest-wireworld/archive/v0.0.4-2.zip

Old Versions:
0.0.3 (Broken) - https://github.com/raymoo/minetest-wireworld/archive/v0.0.3.zip
0.0.2 - https://github.com/raymoo/minetest-wireworld/archive/v0.0.2.zip
0.0.1 - https://github.com/raymoo/minetest-wireworld/archive/v0.0.1.zip

Item Descriptions:
The wireworld blocks, other than the interface, correspond to the normal wireworld cells.

A zapper is a tool that lets you turn conductors into electron heads by left-clicking them.

The on and off interfaces are like new kinds of cells - When one or more electron heads are in its Moore neighborhood, it changes state to on. Otherwise, it turns off (or stays off). This means that the interface will react to neighboring electron heads with a delay of one simulation step.

Mesecons:
Conductors will turn into electron heads on the rising edge of a mesecons signal.

Interfaces output mesecons signals. If you don't want interfaces to interfere with your wireworld circuits, put them so that they are only touching one wireworld cell - that way it won't activate anything when the signal turns on. Of course, there are probably good applications of actually having them interfere. An easy example is instant transmission of wireworld electrons.


IDs:
+ Spoiler



Crafting Recipes:
+ Spoiler


Screenshots:

+ Spoiler

As you can see, it is fairly bare-bones.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 02:37
by Evergreen
Could you post some screenshots of this? Also, the git repository should be the root of the project, there should be an extra folder.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 02:39
by Byakuren
Evergreen wrote:Could you post some screenshots of this? Also, the git repository should be the root of the project, there should be an extra folder.


Where should the extra folder be? And I'll get some screenshots.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 02:57
by Byakuren
I'm assuming you meant that I shouldn't have an extra folder, so I have moved everything up a directory. Also added some screenshots and a new release.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 06:12
by Krock
It's great to see a new version of this mod.
The old one from PilzAdam was limited to the x and z axis.

Please change the title to [Modpack] because those mods need each other.
An idea would also be the compatibility with mesecons, so it would be possible to send a signal with a wireworld circuit.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 06:28
by Byakuren
Krock wrote:It's great to see a new version of this mod.
The old one from PilzAdam was limited to the x and z axis.

Please change the title to [Modpack] because those mods need each other.
An idea would also be the compatibility with mesecons, so it would be possible to send a signal with a wireworld circuit.


Thanks. I didn't know there was a previous wireworld mod, or that there was significant interest. Mesecons compatibility is something I was already thinking about, but I'll have to look at the mesecons api and figure it out.

Re: [Mod] Wireworld Mod

PostPosted: Tue Apr 14, 2015 11:46
by Evergreen
Byakuren wrote:I'm assuming you meant that I shouldn't have an extra folder, so I have moved everything up a directory. Also added some screenshots and a new release.

Yes, that is what I meant. Also, this looks very interesting, I'll try it the next chance I get.

Re: [Modpack] Wireworld Mod

PostPosted: Tue Apr 14, 2015 12:56
by twoelk
somehow I always keep clicking this thread to look for a wireframe view mod XD

Re: [Modpack] Wireworld Mod

PostPosted: Tue Apr 14, 2015 19:17
by ExeterDad
twoelk wrote:somehow I always keep clicking this thread to look for a wireframe view mod XD

Guilty as well :)

Re: [Modpack] Wireworld Mod

PostPosted: Tue Apr 14, 2015 19:57
by prestidigitator
The main mod itself looks cool, but...

Two extra mods and dozens of functions just to loop over the nodes in adjacent positions? That's some mighty obfuscation there. You might want to try just a triple-nested loop, or some mod arithmetic. That way you can easily optimize a bit, too (since it doesn't matter if you have more than 3 heads...). Something like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function count_neighbors(pos, filter, limit)
   local x, y, z = pos.x, pos.y, pos.z;
   if not limit then limit = 26; end;
   
   local c = 0;
   for dx = -1, 1 do
      for dy = -1, 1 do
         for dz = -1, 1 do
            if (dx ~= 0 or dy ~= 0 or dz ~= 0) and filter(minetest.get_node({x=x+dx, y=y+dy, z=z+dz})) then
               c = c + 1;
               if c >= limit then return c; end;
            end;
         end;
      end;
   end;
   
   return c;
end;

local function is_electron_head(node)
   return node.name == "wireworld:electron_head";
end;

local function count_electron_head_neighbors(pos)
   return count_neighbors(pos, is_electron_head, 3);
end;


EDIT: For that matter, you could even just do it like this, since you only count electron heads for a node that is, itself, not one:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function count_electron_head_neighbors(pos)
   local pMin = {x=pos.x-1, y=pos.y-1, z=pos.z-1};
   local pMax = {x=pos.x+1, y=pos.y+1, z=pos.z+1};
   local heads = minetest.find_nodes_in_area(pMin, pMax, { "wireworld:electron_head" });
   return #heads;
end;

Re: [Modpack] Wireworld Mod

PostPosted: Tue Apr 14, 2015 23:24
by Byakuren
prestidigitator wrote:The main mod itself looks cool, but...

Two extra mods and dozens of functions just to loop over the nodes in adjacent positions? That's some mighty obfuscation there. You might want to try just a triple-nested loop, or some mod arithmetic. That way you can easily optimize a bit, too (since it doesn't matter if you have more than 3 heads...). Something like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function count_neighbors(pos, filter, limit)
   local x, y, z = pos.x, pos.y, pos.z;
   if not limit then limit = 26; end;
   
   local c = 0;
   for dx = -1, 1 do
      for dy = -1, 1 do
         for dz = -1, 1 do
            if (dx ~= 0 or dy ~= 0 or dz ~= 0) and filter(minetest.get_node({x=x+dx, y=y+dy, z=z+dz})) then
               c = c + 1;
               if c >= limit then return c; end;
            end;
         end;
      end;
   end;
   
   return c;
end;

local function is_electron_head(node)
   return node.name == "wireworld:electron_head";
end;

local function count_electron_head_neighbors(pos)
   return count_neighbors(pos, is_electron_head, 3);
end;


EDIT: For that matter, you could even just do it like this, since you only count electron heads for a node that is, itself, not one:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function count_electron_head_neighbors(pos)
   local pMin = {x=pos.x-1, y=pos.y-1, z=pos.z-1};
   local pMax = {x=pos.x+1, y=pos.y+1, z=pos.z+1};
   local heads = minetest.find_nodes_in_area(pMin, pMax, { "wireworld:electron_head" });
   return #heads;
end;


Thanks for the feedback.

I already implemented the find_nodes_in_area fix in the repo version a few hours ago (This commit: https://github.com/raymoo/minetest-wire ... e21b1a4958).

I didn't intend to do any obfuscation with those two modules. The Church module was intended to reimplement some functions I was familiar with - they wouldn't normally be custom functions. I can probably reduce the size of bobutil though, since I'm not using the neighbors function I was using before.


EDIT: Actually, the only thing that might deserve to be its own module is Church, unless I expanded BobUtil to be a bit more general, and there are probably already similar libraries around. The reason I made them separate mods though, is that I haven't figured out how to split my code across different files otherwise. Since the mod folder doesn't seem to be part of the lua path, I don't know how to include other files.

EDIT2: I also did not know about the pound sign operator. I will include that in my code too.

Re: [Modpack] Wireworld Mod

PostPosted: Wed Apr 15, 2015 05:17
by prestidigitator
Byakuren wrote:I haven't figured out how to split my code across different files otherwise. Since the mod folder doesn't seem to be part of the lua path, I don't know how to include other files.

Ah. Yeah. It's a bit of a shame the Minetest environment doesn't take advantage of standard Lua modules/packages/require. You can make it work, but it's a pain. Actually modules could really have been used pretty much instead of the whole mod+depends.txt thing. But whatever.

To execute code in another file use minetest.get_current_modname(), minetest.get_modpath(), and dofile(). Using dofile() will essentially call the code in another file as if it is in the body of a function with no parameters. It returns whatever that code returns. So you can either call and expect side effects (e.g. addition of global variables), or you can return value(s) from it. For example, you could write something like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local MOD_NAME = minetest.current_modname();
local MOD_PATH = minetest.get_modpath(MOD_NAME);

local BobUtil = dofile(MOD_PATH .. "/BobUtil.lua");


And you could have BobUtil.lua leave up to the caller the choice of whether or not to add it to the global namespace:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local BobUtil = {};

local function BobUtil.myfunc()
   -- ...
end;

return BobUtil;


It looks sort of like Lua modules, just without the nice module() and require() functions and their use of the standard package.* stuff.

Re: [Modpack] Wireworld Mod

PostPosted: Wed Apr 15, 2015 06:00
by Byakuren
I didn't know you could return functions with dofile and lua files, that will let me keep BobUtil from escaping into the global scope. Thanks again.

Re: [Modpack] Wireworld Mod

PostPosted: Wed Apr 15, 2015 14:54
by Evergreen
I just tried this, and it works very nicely. Good job on reviving tis idea.

Re: [Modpack] Wireworld Mod

PostPosted: Wed Apr 15, 2015 20:32
by Byakuren
Added mesecons support, and a crafting recipe for the zapper.

EDIT: Actually, that broke something. I should have tested it a bit more.

EDIT2: I think I have a good idea for a fix.

Re: [Modpack] Wireworld Mod

PostPosted: Wed Apr 15, 2015 22:06
by Byakuren
Released version 0.0.4. This version fixes the problem with 0.0.3 by adding special blocks for detecting wireworld electrons, rather than having electron heads be receptors themselves. Also added more information to the OP

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 00:27
by Evergreen
It appears your code still depends on bobutil, even though it doesn't exist in the current version:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
2015-04-15 20:24:58: ERROR[main]: The following mods could not be found: "bobutil"
2015-04-15 20:24:58: ERROR[main]: ========== ERROR FROM LUA ===========
2015-04-15 20:24:58: ERROR[main]: Failed to load and run script from
2015-04-15 20:24:58: ERROR[main]: /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:
2015-04-15 20:24:58: ERROR[main]: cannot open /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/lib/bobutil.lua: No such file or directory
2015-04-15 20:24:58: ERROR[main]: stack traceback:
2015-04-15 20:24:58: ERROR[main]:       [C]: in function 'dofile'
2015-04-15 20:24:58: ERROR[main]:       ...ns/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:3: in main chunk
2015-04-15 20:24:58: ERROR[main]: ======= END OF ERROR FROM LUA ========
2015-04-15 20:24:58: ERROR[main]: Server: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua
2015-04-15 20:24:58: ERROR[main]: ModError: ModError: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 00:45
by Byakuren
Evergreen wrote:It appears your code still depends on bobutil, even though it doesn't exist in the current version:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
2015-04-15 20:24:58: ERROR[main]: The following mods could not be found: "bobutil"
2015-04-15 20:24:58: ERROR[main]: ========== ERROR FROM LUA ===========
2015-04-15 20:24:58: ERROR[main]: Failed to load and run script from
2015-04-15 20:24:58: ERROR[main]: /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:
2015-04-15 20:24:58: ERROR[main]: cannot open /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/lib/bobutil.lua: No such file or directory
2015-04-15 20:24:58: ERROR[main]: stack traceback:
2015-04-15 20:24:58: ERROR[main]:       [C]: in function 'dofile'
2015-04-15 20:24:58: ERROR[main]:       ...ns/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:3: in main chunk
2015-04-15 20:24:58: ERROR[main]: ======= END OF ERROR FROM LUA ========
2015-04-15 20:24:58: ERROR[main]: Server: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua
2015-04-15 20:24:58: ERROR[main]: ModError: ModError: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua


Are you sure? bobutil isn't in the depends for wireworld, and I'm not getting the same error.

EDIT: Found the problem to the file not found error, but it was because I hadn't added the new bobutil file to the repo. I probably should have just done a git mv. I think the "mod missing" message is because you still have bobutil included in your world, though.

EDIT2: I have applied the fix.

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 01:07
by Evergreen
Byakuren wrote:
Evergreen wrote:It appears your code still depends on bobutil, even though it doesn't exist in the current version:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
2015-04-15 20:24:58: ERROR[main]: The following mods could not be found: "bobutil"
2015-04-15 20:24:58: ERROR[main]: ========== ERROR FROM LUA ===========
2015-04-15 20:24:58: ERROR[main]: Failed to load and run script from
2015-04-15 20:24:58: ERROR[main]: /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:
2015-04-15 20:24:58: ERROR[main]: cannot open /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/lib/bobutil.lua: No such file or directory
2015-04-15 20:24:58: ERROR[main]: stack traceback:
2015-04-15 20:24:58: ERROR[main]:       [C]: in function 'dofile'
2015-04-15 20:24:58: ERROR[main]:       ...ns/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:3: in main chunk
2015-04-15 20:24:58: ERROR[main]: ======= END OF ERROR FROM LUA ========
2015-04-15 20:24:58: ERROR[main]: Server: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua
2015-04-15 20:24:58: ERROR[main]: ModError: ModError: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua


Are you sure? bobutil isn't in the depends for wireworld, and I'm not getting the same error.

EDIT: Found the problem to the file not found error, but it was because I hadn't added the new bobutil file to the repo. I probably should have just done a git mv. I think the "mod missing" message is because you still have bobutil included in your world, though.

EDIT2: I have applied the fix.

Good, it works now. Also, you should probably make the on state of the mesecons interface not available in teh creative inventory, and you should also make it drop the off state version of it when dug.

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 01:11
by Byakuren
Evergreen wrote:
Byakuren wrote:
Evergreen wrote:It appears your code still depends on bobutil, even though it doesn't exist in the current version:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
2015-04-15 20:24:58: ERROR[main]: The following mods could not be found: "bobutil"
2015-04-15 20:24:58: ERROR[main]: ========== ERROR FROM LUA ===========
2015-04-15 20:24:58: ERROR[main]: Failed to load and run script from
2015-04-15 20:24:58: ERROR[main]: /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:
2015-04-15 20:24:58: ERROR[main]: cannot open /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/lib/bobutil.lua: No such file or directory
2015-04-15 20:24:58: ERROR[main]: stack traceback:
2015-04-15 20:24:58: ERROR[main]:       [C]: in function 'dofile'
2015-04-15 20:24:58: ERROR[main]:       ...ns/minetest-dev/bin/../mods/wireworld/wireworld/init.lua:3: in main chunk
2015-04-15 20:24:58: ERROR[main]: ======= END OF ERROR FROM LUA ========
2015-04-15 20:24:58: ERROR[main]: Server: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua
2015-04-15 20:24:58: ERROR[main]: ModError: ModError: Failed to load and run /home/evergreen/programs/minetest_versions/minetest-dev/bin/../mods/wireworld/wireworld/init.lua


Are you sure? bobutil isn't in the depends for wireworld, and I'm not getting the same error.

EDIT: Found the problem to the file not found error, but it was because I hadn't added the new bobutil file to the repo. I probably should have just done a git mv. I think the "mod missing" message is because you still have bobutil included in your world, though.

EDIT2: I have applied the fix.

Good, it works now. Also, you should probably make the on state of the mesecons interface not available in teh creative inventory, and you should also make it drop the off state version of it when dug.


It does drop the off version, but I'll set it to not appear in creative,

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 15:14
by Evergreen
Good job! This could potentially be very useful for mesecons contraptions.

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 17:12
by Byakuren
Evergreen wrote:Good job! This could potentially be very useful for mesecons contraptions.


There isn't really anything you can compute with wireworld that you can't already due with mesecons more easily, even if you exclude luacontrollers. The advantages with wireworld I see is that it looks nice, and you can have fun messing with more configurations.

Another thing is that the active range limits the size of wireworld circuits, since clock generators/loops will go out of sync if they leave your active range. This could be solved by increasing the active range, but that might be impractical if you are using a low-power machine, or are a server.

Re: [Modpack] Wireworld Mod

PostPosted: Thu Apr 16, 2015 21:07
by Evergreen
Byakuren wrote:
Evergreen wrote:Good job! This could potentially be very useful for mesecons contraptions.


There isn't really anything you can compute with wireworld that you can't already due with mesecons more easily, even if you exclude luacontrollers. The advantages with wireworld I see is that it looks nice, and you can have fun messing with more configurations.

Another thing is that the active range limits the size of wireworld circuits, since clock generators/loops will go out of sync if they leave your active range. This could be solved by increasing the active range, but that might be impractical if you are using a low-power machine, or are a server.

You could use rubenwardy's anchor mod to keep the chunks loaded, but you are right. It is more about novelty than anything else.

Re: [Modpack] Wireworld Mod

PostPosted: Fri Apr 17, 2015 04:00
by prestidigitator
Evergreen wrote:You could use rubenwardy's anchor mod to keep the chunks loaded, but you are right. It is more about novelty than anything else.

You could also run the simulation independently of the nodes, and simply have the nodes act as a GUI for the simulation (a view-controller for the simulation's model). That would also be a good way to ensure the integrity of the cellular automata, though it also introduces complications such as determining which nodes belong to which simulations (it wouldn't work too well to have a simulation that's big enough to cover all nodes everywhere at once—or, at least, it introduces data structure complications for determining neighbors, etc.).

Re: [Modpack] Wireworld Mod

PostPosted: Fri Apr 17, 2015 04:58
by Byakuren
prestidigitator wrote:
Evergreen wrote:You could use rubenwardy's anchor mod to keep the chunks loaded, but you are right. It is more about novelty than anything else.

You could also run the simulation independently of the nodes, and simply have the nodes act as a GUI for the simulation (a view-controller for the simulation's model). That would also be a good way to ensure the integrity of the cellular automata, though it also introduces complications such as determining which nodes belong to which simulations (it wouldn't work too well to have a simulation that's big enough to cover all nodes everywhere at once—or, at least, it introduces data structure complications for determining neighbors, etc.).


Since empty space doesn't do anything in wireworld, I was thinking I could have some way to register a group of "connected" blocks as a simulation, where two nodes are connected if they are in each other's Moore neighborhood, or if they are both connected to a third node.

Simulating wireworld separate from the nodes would also let me use a timestep lower than 1.

Some disadvantages I see with this approach would be that it takes more effort (and potential bugginess) in handling what happens to a simulation when nodes are removed. The simplest solution would just be to break the simulation, I guess. The nodes that become part of a simulation could store some unique name for the simulation, and then tell it to die if the node is removed.

I have a couple of modding questions, though. How would I make something happen at a set interval, independent of nodes? Use minetest.after on a function that itself passes itself to after? Also, I don't know what the popular way to serialize mod data. Writing a file to the mod directory would work, but maybe there is some built in data store place designed for storing mod state.

Re: [Modpack] Wireworld Mod

PostPosted: Fri Apr 17, 2015 07:00
by prestidigitator
Byakuren wrote:Some disadvantages I see with this approach would be that it takes more effort (and potential bugginess) in handling what happens to a simulation when nodes are removed. The simplest solution would just be to break the simulation, I guess. The nodes that become part of a simulation could store some unique name for the simulation, and then tell it to die if the node is removed.


Yes. Exactly. Removing nodes would required a connectedness test, which is possibly almost as difficult as connecting them up in the first place would be (if you weren't doing it incrementally). I suppose it could be done globally if it's a sparse list, but that could grow to be a pretty big set of updates eventually. It would also require a redundant persistence of state unless only those nodes loaded so far since the server was started were to be used.

Byakuren wrote:I have a couple of modding questions, though. How would I make something happen at a set interval, independent of nodes? Use minetest.after on a function that itself passes itself to after? Also, I don't know what the popular way to serialize mod data. Writing a file to the mod directory would work, but maybe there is some built in data store place designed for storing mod state.

Probably minetest.register_globalstep() with a counter to run only so often (probably wouldn't want to do it every single server frame).