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

I'll summerize the question to the best of my ability, and hope that I don't oversummerize.

Basically, I'm working on an RPG Engine in Perl, and I need some way to keep track of the locations of various items/creatures in the world.

I've been considering using an three dimentional array, however as the world would often be rather large, (example grid of 10,000x10,000x100), I'm not sure it's the wisest approach because of the memory it would take up... (Do empty array elements take up much space?)

Can anyone suggest any alternatives, or ways I can make the array idea work without using up too much memory?

If I need to elaborate on anything, please just mention it.


"Weird things happen, get used to it"

Flame ~ Lead Programmer: GMS
http://gms.uoe.org
  • Comment on RPG Engine Location Tracking (Large Three Dimentional Array?)

Replies are listed 'Best First'.
(rtfss) Re: RPG Engine Location Tracking (Large Three Dimentional Array?)
by jackdied (Monk) on Oct 25, 2001 at 08:19 UTC
    (Required: Trying First Super Search)
    You may want to look at yesterday's asked and answered question : Map Storage For Game

    -jackdied

Re: RPG Engine Location Tracking (Large Three Dimentional Array?)
by Fletch (Bishop) on Oct 25, 2001 at 07:40 UTC

    Empty array elements do take up space. Empty hash elements don't take up any space, so that might be a better idea space wise than an array.

    A better way to approach it might be to have be-able locations (for lack of a better term :) be containers which can return a list of their contents upon request.

Re: RPG Engine Location Tracking (Large Three Dimentional Array?)
by fokat (Deacon) on Oct 25, 2001 at 17:56 UTC
    Sometimes, this kind of problem can be solved easily when turned upside down. I understand that you want to keep a representation of your world in memory. The method you expose has important drawbacks from a memory usage standpoint. Probably, Perl6's lazy lists might come handy, but we do not have that yet, do we?

    A more conservative approach, would be to have each object track its own position within the world, as a set of three coordinates which is what your array suggests. You could have something like...

    package BaseItem; sub moveto ($$$$) { my $self = shift; my $new_x = shift; my $new_y = shift; my $new_z = shift; ... } sub position ($) { my $self = shift; return ($self->{x}, $self->{y}, $self->{z}); } ...
    This would be a basic item in your game, providing some basic properties such as the ability to move and the ability to report its current position.

    Regular items might be something like:

    package Item; our @ISA = qw(BaseItem); ...
    So they inherit the properties of BaseItem such as the position and possibly things like mass, volume or standard modifiers.

    I would then build a class Container which could be used to hold a (number of) objects, moving them all together. This class could also be used in the Player class, as players can carry things with them.

    Since normaly you tend to have a smaller number of objects than rooms in your world, it makes more sense to scan the list of objects in order to find which are in a given room, specially since you do not need to figure this out every time for every room.

    If you want to go multiplayer or even massively multiplayer, a database backend might be used to store the object and player data. But I digress...

    Grouping base properties of the items in classes like these, would also allow you to build caches to reduce the work associated with drawing a room. A cache might very well hold in a hash or similar structure, where are the objects since this would only need to hold a part of the world at a time.

    As you might guess from this post, I have had a bit of work in this area before and would be willing to devote some spare time to something like what you're building.

    Good luck...

Re: RPG Engine Location Tracking (Large Three Dimentional Array?)
by flocto (Pilgrim) on Oct 25, 2001 at 15:42 UTC
    I'm not entirely sure if this would work, but it's an idea:
    First, fork off a child that is able to change each players object. This process could check (e.g. periodically, once per second or so) that every player-object has the rooms around it loaded and deletes not used rooms again.
    Now the main programm should be able to go in whatever direction is allowed (by the room the player is currently in) and just "go" there without having to load anything. Now you could send a signal to the child (or have it check after some time, or both) and the child loads the nine new rooms and forgets the old nine. Then all you'd need is a 9x9x9 array for each player. And if you use only six directions (up, down, right, left, forward, backward) you can use an even smaller array.

    That's the idea.. Hope it was of any help ;)
    -octo-
    --
    GED/CC d-- s:- a--- C++(+++) UL+++ P++++$ L++>++++ E--- W+++@ N o? K? w-- O- M-(+) V? !PS !PE !Y PGP+(++) t-- 5 X+ R+(+++) tv+(++) b++@ DI+() D+ G++ e->+++ h!++ r+(++) y+
Well... (Database?)
by Flame (Deacon) on Oct 25, 2001 at 23:54 UTC
    Thanks for the ideas everyone, unfortunately many of them rely on having it indoors... much of the world I'm attempting to design is actually outdoors... So I need to be able to keep track of where everything is in relation to anythign else quickly, for example, a 10x10x10 'Viewing Window' in which the player can see everything...

    I've had an idea though, I cannot say how well it will work. I'm considering using a flat-file database to store object id's (theres an item array already in use) and look up all the item id's in the given area.

    I'm currently looking at DBI-Sprite, however I don't know if it's the best idea as I don't know how it works...

    Anyone know if using DBI-Sprite is a good idea? Or with my expanded explanation can anything else be thought of?

    (I realize that this is rather poorly worded, I just came back from school and I'm kinda tired at the moment...)


    "Weird things happen, get used to it"

    Flame ~ Lead Programmer: GMS
    http://gms.uoe.org
      Edit: Added Error and the code

      Well, after a bit of experementation, I don't think Sprite is going to help... (I can't even get it to set up a table...)

      Anyone know what this is suppost to mean?
      perl worldbuild.pl
      
      Oops! Sprite encountered the following error when processing your request:
      
          Cannot write the database to output file. (\\world.stb)
      
      Here's some more information to help you:
      
              file:
          No such file or directory
      
      DBD::Sprite::db do failed: -511:Cannot write the database to output file.(\\worl
      d.stb) at worldbuild.pl line 8.
      
      


      This is the code:
      use strict; use DBI; my $DBI; $ENV{SPRITE_HOME} = "E:\\PRPG\\World\\"; $DBI = DBI->connect('DBI:Sprite:WORLD') || die "Could not connect (".$ +DBI->err.':'.$DBI->errstr.")!"; $DBI->do("CREATE TABLE WORLD (UID INT, X INT, Y INT, Z INT, IID INT)") +;



      "Weird things happen, get used to it"

      Flame ~ Lead Programmer: GMS
      http://gms.uoe.org
Oops, forgot to mention
by Flame (Deacon) on Oct 25, 2001 at 06:50 UTC
    Note: It would be a 3D array of objects.


    "Weird things happen, get used to it"

    Flame ~ Lead Programmer: GMS
    http://gms.uoe.org
      Make sure your RPG has a heartbeat. Once per beat, update what objects you are keeping tabs on based on activity.If we had a "shotgun" home of 100 rooms, and I am in room 1, there is no need to keep it in memory and ready for use because there is no way anyone can make interact with room 100 in the current heartbeat. With this method you can use a minimal amount of memory for your environment.