Py Question : Calling upon the Factorio Lords...

Anything that prevents you from playing the game properly. Do you have issues playing for the game, downloading it or successfully running it on your computer? Let us know here.
Post Reply
BanRevenant
Manual Inserter
Manual Inserter
Posts: 2
Joined: Fri Mar 15, 2024 11:09 pm
Contact:

Py Question : Calling upon the Factorio Lords...

Post by BanRevenant »

I come to you, cap in hand, at the end of my rope. The epitome of ineptitude, unable to muster the simplest command while maintaining a head full of hair.

I desperately want to load a Factorio server via Python, with the support of STDin/out. Bestow upon this feeble-minded soul the incantations needed to achieve this feat without resorting to the dark arts of RCON. Any tips, tricks, or enchanted scripts you could share would not only save my sanity but might just make you a hero that saves me from my demise.

Here is a sample script of mine.

Code: Select all

import asyncio
import subprocess

async def run_factorio_server():
    factorio_exe = "Factorio Server\\bin\\x64\\factorio.exe"
    save_file = "Factorio Server\\saves\\JustMap.zip"

    # Command to start the Factorio server with the specified save file
    command = f'"{factorio_exe}" --start-server "{save_file}"'

    process = await asyncio.create_subprocess_shell(
        command,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

    print("started...")


    async def read_output():
        while True:
            line = await process.stdout.readline()
            if line:
                print("Server output:", line.decode().strip())
            else:
                break 

    async def send_commands():
        await asyncio.sleep(10)
        print("Sending /save command to Factorio server...")
        process.stdin.write(b"/save\n")
        await process.stdin.drain()

        await asyncio.sleep(10)  
        print("Sending /quit command to stop the server...")
        process.stdin.write(b"/quit\n")
        await process.stdin.drain()

    await asyncio.gather(
        read_output(),
        send_commands()
    )


    await process.wait()
    print("stopped")

if __name__ == "__main__":
    asyncio.run(run_factorio_server())
Thank you for listening to the pleas of a desperate soul. Your wisdom and mercy are my last hope...

SoShootMe
Filter Inserter
Filter Inserter
Posts: 481
Joined: Mon Aug 03, 2020 4:16 pm
Contact:

Re: Py Question : Calling upon the Factorio Lords...

Post by SoShootMe »

"Py" in the context of Factorio suggests Pyanodon's mods so it's probably a good idea to rename this topic. (I'm also not sure it belongs in Technical help, but that's something for the moderators to deal with.)

I think your approach can't work because Factorio doesn't seem to use stdin/stdout for console commands (at least on Windows as you are using), and even if it did, it would at best be impractical for reliable request/response-type communication for multiple reasons (although this doesn't apply to your sample script). I don't think it is the problem here but considering the general case, you must either not connect stderr of the subprocess to a pipe, or also read the stderr pipe to ensure the subprocess does not block.

Although I have not used it, there is factorio-rcon-py on PyPI so "the dark arts of RCON" (which I find ironic from someone using coroutines since, at least to me, they more fundamentally fit that description) may not be prerequisite knowledge.

Post Reply

Return to “Technical Help”