muba has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am writing a small single player MUD like hack'n'slash game. (Yes, I had a question with this before :)

The enemies and other NPC (non-player characters) of course have to walk around. Before now, everyone was allowed to take one step after the player had done something. Now I want to make it less "frozen".

So I first had a look at thread but my system (Windows 98 SE, ActivePerl 5.6.1) does not support that. So I had a look at fork. Well, that works fine, except for one thing: inside the fork, the data (such as player locations, NPC locations, all those stuff) are not correct.

So I grabbed the fork documentation and I found out that variables and such are copied. How can I, from within the fork, access the data of the main process?
  • Comment on Data copied with fork() -> how to access true data?

Replies are listed 'Best First'.
Re: Data copied with fork() -> how to access true data?
by Joost (Canon) on May 31, 2004 at 21:51 UTC
    Well, if you want to use threads, you can get a more recent perl with better thread support, or take a look at forks - it emulates the newer thread API using fork().

    OTOH, you might use something like POE to get callbacks into 1 process/thread whenever an event is triggered. You could maybe even get away with using alarm() to trigger your own timeouts if you want to get that low-level.

    If you are using Tk or some other GUI toolkit, most of them also have some kind of event handling to accomodate this kind of thing (see Tk::Eventloop for instance)

    One other strategy that might help if you run multiple processes already (say, for instance you're running the game from CGI or mod_perl) is to use a shared data storage (like a relational database), so all data can be shared "automatically" as long as you check for updates periodically. Other options here are IPC::ShareLite and Cache::Cache.

    Have fun figuring out which one you like :-)

    Joost.

      It's text based, not internet connected, so no Tk, no CGI, no mod_perl. But I'll check out the other things!

      Thanks a lot!

      Besides... I know almost nothing about databases so that would be one of the last things I'll do, but thanks for the hint anyway.

        "...not internet connected..."

        Wouldn't that make it a SUD? :)

        cLive ;-)

Re: Data copied with fork() -> how to access true data?
by BrowserUk (Patriarch) on May 31, 2004 at 22:45 UTC
    So I grabbed the fork documentation and I found out that variables and such are copied. How can I, from within the fork, access the data of the main process?

    You can't!.

    That's the main difference between forks and threads. Threads allow shared data access, forks do not. You can use various mechanisms to indirectly share inormation between forked processes, sockets, shared ram etc. but you cannot share direct access to the same data.

    I'm confused. You say that you looked at threads, but they aren't supported on your OS/perl combination, but that fork works. What confuses me is, on Windows, fork is emulated using threads. So if fork works, then I thought that Thread should also work, but maybe not.

    Update: How quickly we (I) forget. I found this whilst attempting to refresh my memory.

    I've never used Perl on '98. It is possible (though it seems unlikely) that the fork emulation is enabled but not the threading?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
      So, it seems that the most easiest way is to install 5.8.x?
      That's ok, then.

      I know this is some kind of a FAQ, but will my code (not only for this game, but all of my Perl code) need to be rewritten?

        That's probably a good move anyway, though if there is any chance that you could upgrade your OS to something less than 10 years old, that would probably help your cause enormously also :)

        With respect to rewriting your perl code, probably not.

        For the most part, anything that runs on 5.6.1 should run on 5.8.x with minimal changes. That's a risky generalisation to make without having seen the code in question, but based on my own usage of both, it's not too wild a guess. Of course, my memory could be playing tricks on me again.

        The harder question is how much effort will be required to make your current single threaded code run multi-threaded. On that, I will not even hazard a guess.

        From the little information I have, your app is basically a big loop that get user input, uses it to modify the state of the current player, takes the opportunity to update the state of your NPC's and loops back for input.

        Your desire is for the NPC's to run independantly of the user input. In theory, sharing the variables that contain their state with a background thread that loops over a sleep and modifies their behaviour is pretty trivial, but the devil is in the detail.

        If your NPC's are OO-modelled, or if their state is maintained in nested hashes, or any number of other standard perl techniques, then the modifications could be awkward.

        It may make more sense to simple use a timeout on your user input (using Term::ReadKey or similar), and just allow the NPC's to continue their state changes whilst the user thinks about his input.

        How much effort would be involved, and whether multithreading would be beneficial relative to the other options available, will depend highly upon how your code is currently structured and how you want to modify it.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail