Factorio Player Health on LED strip
Factorio Player Health on LED strip
Hi there,
I've been enjoying a lot Factorio during the last months, but I've also been busy playing around with my LED strips.
One day I thought, hey, why not combine Factorio with my LEDs
I don't think this really qualifies as a "Mod" because it's kind of more low-level.
So I hacked around a bit and finally got it working, my LED strip can now display the Player Health
In theory, any numerical value from the game is possible to display (also in any color) but I jsut used the player health as a simple example.
In this video I just run into some enemies on an empty map to show that it works: https://www.youtube.com/watch?v=4T1cs6--wXU
Hope you find that as sweet as I do
@Factorio Team: Thanks a LOT for leaving in the symbol names in the Linux binary <3
I've been enjoying a lot Factorio during the last months, but I've also been busy playing around with my LED strips.
One day I thought, hey, why not combine Factorio with my LEDs
I don't think this really qualifies as a "Mod" because it's kind of more low-level.
So I hacked around a bit and finally got it working, my LED strip can now display the Player Health
In theory, any numerical value from the game is possible to display (also in any color) but I jsut used the player health as a simple example.
In this video I just run into some enemies on an empty map to show that it works: https://www.youtube.com/watch?v=4T1cs6--wXU
Hope you find that as sweet as I do
@Factorio Team: Thanks a LOT for leaving in the symbol names in the Linux binary <3
- Kewlhotrod
- Fast Inserter
- Posts: 166
- Joined: Thu Apr 23, 2015 5:20 pm
- Contact:
Re: Factorio Player Health on LED strip
aha this is really sweet, you need to make a power version so when power gets low, disco lights start flashing. maybe add a horn sound too.
Re: Factorio Player Health on LED strip
This. Is. Genius.
Koub - Please consider English is not my native language.
Re: Factorio Player Health on LED strip
This is really cool. What programs did you use to get it going?
Re: Factorio Player Health on LED strip
I know how he did it.
Factorio-> MAGIC ARTIFACT -> external LED interface.
duh. obvious.
Factorio-> MAGIC ARTIFACT -> external LED interface.
duh. obvious.
Re: Factorio Player Health on LED strip
Moved to Show your Creations, but I left a link in General.
I would like to see the code.
I would like to see the code.
Cool suggestion: Eatable MOUSE-pointers.
Have you used the Advanced Search today?
Need help, question? FAQ - Wiki - Forum help
I still like small signatures...
Have you used the Advanced Search today?
Need help, question? FAQ - Wiki - Forum help
I still like small signatures...
Re: Factorio Player Health on LED strip
My initial approach was to convert the number I wanted to get out of the game (player life percent) to a binary representation in Lua and then call a function for every 1 and call a function for every 0.
This gets called every tick.
I would then run Factorio in GDB to register hooks when the breakpoint of the Lua function in the binary was hit. This example is valid for Factorio 0.12.33.
/usr/local/bin/factorioHook was just a shell script that wrote to a FIFO in /tmp that was created with a C program that was running as a local daemon.
This program would read the value from the FIFO, reassemble the Integer and then send it via UDP to the Raspberry Pi over UDP.
The Raspberry Pi was just running a trivial UDP server to listen for the value to display.
This was a lot of nasty hacking, a lot too much because the game was lagging at 12 FPS on my new Laptop.
The next thing I found out after registering hooks on breakpoints for the Factorio binary was that game.write_file() exists xD
This made it far easier because now all I needed to do was write the Integer value to a file in the script-output/ folder and read that file from my local C daemon, no binary calculation, GDB debugging or FIFO required anymore; it also runs at 60 FPS now ^^
In the end I did a lot of redudant work but still learned a lot about debugging and Linux binary formats as well as 64 Linux calling conventions (my very first approach was to rewrite the functions for the Lua functions in the Linux binary...^^).
But now it works and I can finally put my LED strip to good use.
Maybe I will clean up the source code and release it so everyone with Raspberry Pi and a WS2801 LED strip can use it (also not using GDB anymore improved the practicability by a great bit).
This gets called every tick.
Code: Select all
...
function pushBits2flashlight(originalInt, bitArray)
dontcare = game.darkness -- reset signal
for cnt, bit in ipairs(bitArray) do
if bit == 0 then
game.player.disable_flashlight() -- send 0
elseif bit == 1 then
game.player.enable_flashlight() -- send 1
else
print("pushBits2flashlight: UNEXPECTED VALUE IN bitArray")
end
end
end
...
Code: Select all
break _ZN13LuaGameScript15luaReadDarknessEP9lua_State
commands
silent
shell /usr/local/bin/factorioHook r
continue
end
break _ZN10LuaControl20luaDisableFlashlightEP9lua_State
commands
silent
shell /usr/local/bin/factorioHook 0
continue
end
break _ZN10LuaControl19luaEnableFlashLightEP9lua_State
commands
silent
shell /usr/local/bin/factorioHook 1
continue
end
run
This program would read the value from the FIFO, reassemble the Integer and then send it via UDP to the Raspberry Pi over UDP.
Code: Select all
...
for (;;) {
fifo = open(fifoNAME, O_RDONLY);
bytes = read(fifo, buf, 1);
close(fifo);
printf("Received (%d bytes): %s \n", bytes, buf);
if ( buf[0] == 'r' ) {
printf("RESET SIGNAL!\n");
i=0;
continue;
}
else if ( buf[0] != '0' && buf[0] != '1' ) {
printf("GOT FUCKED UP VALUE!\n");
continue;
}
strncpy(&intAssembling[i], buf, 1);
i++;
if (i >= 8) {
assembled = assembleINT(intAssembling);
// put tha shit on the wire
sprintf(udpBUF, "%d", assembled);
printf("Sending %d to Raspi!\n", assembled);
sendto(socke, udpBUF, strlen(udpBUF)/*+1*/, 0, (struct sockaddr*) &dest, (socklen_t) sizeof(struct sockaddr_in));
i = 0;
}
}
...
Code: Select all
...
def percent2strip(self, percent, col):
"""Light up 'percent' percent of the strip.
This value is between 0 and 100."""
leds2light = int(float(NUMBER_OF_PIXELS) * (float(percent)/100)) # calculate how many LEDs to light
print "Will light %d of %d LEDs (%d%%)" % (leds2light, NUMBER_OF_PIXELS, percent)
self.ledpixels = [color(0,0,0)]*(NUMBER_OF_PIXELS-leds2light) + [col]*leds2light
self.writeStrip(self.ledpixels)
...
The next thing I found out after registering hooks on breakpoints for the Factorio binary was that game.write_file() exists xD
This made it far easier because now all I needed to do was write the Integer value to a file in the script-output/ folder and read that file from my local C daemon, no binary calculation, GDB debugging or FIFO required anymore; it also runs at 60 FPS now ^^
In the end I did a lot of redudant work but still learned a lot about debugging and Linux binary formats as well as 64 Linux calling conventions (my very first approach was to rewrite the functions for the Lua functions in the Linux binary...^^).
But now it works and I can finally put my LED strip to good use.
Maybe I will clean up the source code and release it so everyone with Raspberry Pi and a WS2801 LED strip can use it (also not using GDB anymore improved the practicability by a great bit).
Re: Factorio Player Health on LED strip
This is AWESOME!!
How about arduino? Rasberi Pi seems like overkill.
How about arduino? Rasberi Pi seems like overkill.
Re: Factorio Player Health on LED strip
I love this.
Enjoy it while you can, I'd say, hehe.
Probably you've just reminded them to invoke "strip" in their build script for release buildsraid wrote:@Factorio Team: Thanks a LOT for leaving in the symbol names in the Linux binary <3
Enjoy it while you can, I'd say, hehe.
Is your railroad worrying you? Doctor T-Junction recommends: Smart, dynamic train deliveries with combinator Magick
Re: Factorio Player Health on LED strip
Awsome. you could use an Arduino and try and create a supplementary control panel using that can switch weapons and fire the weapon
Re: Factorio Player Health on LED strip
This is way too complicated. Do you know that you can just output text into a file?
Re: Factorio Player Health on LED strip
kovarex wrote:This is way too complicated. Do you know that you can just output text into a file?
raid wrote:This was a lot of nasty hacking, a lot too much because the game was lagging at 12 FPS on my new Laptop.
The next thing I found out after registering hooks on breakpoints for the Factorio binary was that game.write_file() exists xD
This made it far easier because now all I needed to do was write the Integer value to a file in the script-output/ folder and read that file from my local C daemon, no binary calculation, GDB debugging or FIFO required anymore; it also runs at 60 FPS now ^^
Re: Factorio Player Health on LED strip
I'm seriously considering getting that WS2801 or similar blinkenlights LED strip now and using a r-pi.
I know nothing about modding but I've been meaning to get a R-Pi with a DAC for a while now for another project, but this had added to my reasons to get it.
What's the output/where is it being read?
Damn, there's a lot of possibilities for this. I'm guessing there's another output for player movement. I'd like to animate that strip somehow, even if it's just random lights flashing.
I know nothing about modding but I've been meaning to get a R-Pi with a DAC for a while now for another project, but this had added to my reasons to get it.
What's the output/where is it being read?
Damn, there's a lot of possibilities for this. I'm guessing there's another output for player movement. I'd like to animate that strip somehow, even if it's just random lights flashing.