Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A newbie's in-dev roguelike

8 views
Skip to first unread message

perso...@gmail.com

unread,
Apr 3, 2009, 3:46:39 PM4/3/09
to
So I am working on a roguelike game, my latest revision can be found
at

http://www.filefactory.com/file/af9ca97/n/myrl033009_zip

As you can see, there is sight, a character, a warpable map, graphics,
saving of tiles upon exit. The next step is to save the player. I
worked on that, and the result can be found at

http://www.filefactory.com/file/af9cbad/n/myrl033109_zip

However, it doesn't seem to work...
Anyone care to help me debug this, or have any opinions on it so far?

Mingos

unread,
Apr 3, 2009, 8:29:22 PM4/3/09
to

Saving the player's position works perfectly, I really can't seem to
find any problems with it. Care to specify what exactly is the bug?

As for the opinions:
1. The code is difficult to read. I think you should use the ENTER key
more often. Placing the curly braces and the methods' content in
separate lines isn't a bad thing and it helps in making your code
readable later. Especially when it gets more complex.
2. Were I you, I'd separate the classes' declarations and the methods'
definitions into separate .hpp and .cpp files. Again, there's a
readability problem.
3. Use comments as often as possible. They don't bite. Don't think of
them as of a helpful little thing for other people reading your code.
It's not just doing others a favour, it's also doing yourself a
favour. Eventually you'll forget how exactly your code works.
Memorising what 100 lines of code do is easy. When there are 5000
lines spread over 50 files and you decide to modify something, you'll
curse yourself for not leaving comments.
4. Why do you save absolute positions in pixels rather than the
positions on the grid? I first thought that the player's position "256
384" was the bug you were talking about, but then realised it wasn't
so... It's a bit strange in a grid-based game.
5. I hope you're not planning to keep saving everything in such large
text files. Eventually, the savegames will get humongous. The grid is
24x18 tiles. Uncompressed, it should occupy 432 bytes, plus 2 for the
PC's position. Instead, the tiles occupy 7566 bytes, plus between 5
and 9 for the PC's position. Unless it's just for readability purposes
while the game's in development.

As for the rest... well, it's a good start. Looks a bit like Boulder
Dash (I loved that game, hehe). Hope you can add something interesting
soon to make it playable :). Good luck with it!

[it feels so good to give such advice while I'm struggling with making
my game playable myself, hehehe]

Mingos

perso...@gmail.com

unread,
Apr 3, 2009, 8:46:02 PM4/3/09
to

The bug is very strange. Depending on the order of calling the
saveTiles or savePlayer, either a glibc runtime error occurs upon exit
or it freezes upon exit (the current order freezes), to me at least.
I've read the code over and I haven't found any bug and removing the
savePlayer seems to work, so I am really confused.

1 2 3. I think you refer to the classes when you mean lack of ENTERs,
and the definition vs. declaration. Really I just haven't gotten
around to it but I guess I should before something else comes up. I
also got so caught up that I haven't shaped my comments in yet, but
the relatively little code thus far shouldn't be that hard to read and
insert comments to.

4. That was a bit of laziness, because to recode the tiles self
drawing it would require some additional knowledge only the main
process had, however now it is possible to change that I guess. Thanks
for pointing it out.

5. It's very useful for debugging, and I think until I have many
features of the tiles down I will keep it like this, but yes ideally
they should be changed into binary or some other packed format.

Thanks for viewing my project, my first roguelike :D

-Jerry

Mingos

unread,
Apr 3, 2009, 10:19:06 PM4/3/09
to
On 4 Kwi, 02:46, personje...@gmail.com wrote:
> The bug is very strange. Depending on the order of calling the
> saveTiles or savePlayer, either a glibc runtime error occurs upon exit
> or it freezes upon exit (the current order freezes), to me at least.
> I've read the code over and I haven't found any bug and removing the
> savePlayer seems to work, so I am really confused.

None such thing happened in my case, and I tried several times.
You provided a Windows binary, but since you mention glibc, I assume
your development platform is Linux. Maybe Electric Fence discovers
something?

> 1 2 3. I think you refer to the classes when you mean lack of ENTERs,
> and the definition vs. declaration. Really I just haven't gotten
> around to it but I guess I should before something else comes up. I
> also got so caught up that I haven't shaped my comments in yet, but
> the relatively little code thus far shouldn't be that hard to read and
> insert comments to.

Yes, I referred especially to the classes, and also methods that are
declared and defined within the class declaration, in a single line.
It's true that there's little code, so readability wasn't a BIG
issue... not yet. Still, breaking your code in one class declaration
per .hpp and all its method implementations in one (or more, in case
the total amount of code gets too big) .cpp file is a good practice,
although it becomes visible after you have quite some more code
written.

> 4. That was a bit of laziness, because to recode the tiles self
> drawing it would require some additional knowledge only the main
> process had, however now it is possible to change that I guess. Thanks
> for pointing it out.

As long as the convention works out, there is no need for adopting a
different one. It just seemed very unusual.

> 5. It's very useful for debugging, and I think until I have many
> features of the tiles down I will keep it like this, but yes ideally
> they should be changed into binary or some other packed format.

Yes, I must agree that it's useful for debugging purposes. I sometimes
dump certain stuff, otherwise saved in binary form and compressed,
into human-readable text files. Eliminated quite a few bugs this way.
But the final product shouldn't use such an approach for two reasons:
the files will occupy a considerable amount of disc space, which can
be called "wasted" without risking an exageration, and it makes it too
easy to edit the save files for cheating. Not that I care what the end
user does with the game and the save files, but personally I prefer a
compressed binary.

> Thanks for viewing my project, my first roguelike :D

Again, I must congratulate you. I dumped my first attempt at making a
roguelike game at an earlier stage (had an empty map and a walking
'@', but no map features nor FOV...

[grins at the mention of the word "FOV"... bah, I'm spoiling the big
surprise; I'll announce it during the weekend :)]

I believe it is wise to release early [Darren, will you hate me MUCH
if I release another tech demo instead of a playable game?], since I
find the people's feedback invaluable. Not that I estimate my own
advice in this thread as that important or helpful, but I know I
committed the error of not releasing anything during my first try at
my current game and eventually it ended up in the rubbish bin due to
some bad ideas mixed with unreadable, unmaintainable, dirty code,
terrible management and a naïve top-down apprach to coding... Now I
try to release when there's something new to show and also share all
interesting information via my dev blog, which is an invaluable source
of good advice from its readers. So, to cut it short: I'm happy to see
you appear to do the same :).

Sorry for making this so long; it's well past 4AM and my brainwaves
are getting flat ;)

Mingos

Matthew Allen

unread,
Apr 4, 2009, 1:15:44 PM4/4/09
to
> None such thing happened in my case, and I tried several times.
> You provided a Windows binary, but since you mention glibc, I assume
> your development platform is Linux. Maybe Electric Fence discovers
> something?

I would have guessed it was a memory error before you said this. Now
that you have, I'd say it with 95% confidence. I would guess that
somewhere you are running past the bounds of a buffer that you
allocated on the stack or heap. Look for errant memcpy, strcpy, or
assignment within iteratiors (ie. for(i=0; i<n; i++) n[i] = i types of
structure) and run your code with electric fence (efense)

kaw

unread,
Apr 4, 2009, 1:40:32 PM4/4/09
to
On Apr 4, 4:19 am, Mingos <dominikmarc...@gmail.com> wrote:
> On 4 Kwi, 02:46, personje...@gmail.com wrote:
> > 5. It's very useful for debugging, and I think until I
> > have many features of the tiles down I will keep it like
> > this, but yes ideally they should be changed into binary
> > or some other packed format.
> Yes, I must agree that it's useful for debugging purposes.
> I sometimes dump certain stuff, otherwise saved in binary
> form and compressed, into human-readable text files.
> Eliminated quite a few bugs this way. But the final product
> shouldn't use such an approach for two reasons: the files
> will occupy a considerable amount of disc space, which can
> be called "wasted" without risking an exageration, and it
> makes it too easy to edit the save files for cheating. Not
> that I care what the end user does with the game and the
> save files, but personally I prefer a compressed binary.

I didn't get the download link to work, so I can't comment
on the game or the bug, but I'd like to provide a counterpoint
to this. Keeping your save files in a text format instead of
a binary format likely only (approximately) multiplies their
size by a constant. If you simply add a layer of compression
(e.g. gzip) for release versions, even that effect is almost
eliminated.

I'd say you should keep your save format in the way that's
easiest to read and write, or most helpful in debugging,
and then simply it run through compression (at least for
release versions). Concentrate on writing your game, not on
writing an optimized save file format.

As for cheating, I really don't think it matters. People
should play your game without cheating because it's most fun
without cheating, not because the save file format is hard to
modify. If it's _not_ most fun to play without cheating, why
would you want to ruin what fun they _are_ getting out of
your game?

As an example of this in practice, GearHead uses an ASCII
file format, easily modifiable and even uncompressed. (The
saved games are large, but I don't think it really bothers
anyone.)
-kaw

Mingos

unread,
Apr 4, 2009, 3:20:46 PM4/4/09
to
On 4 Kwi, 19:40, kaw <tqneiq...@sneakemail.com> wrote:
> I didn't get the download link to work, so I can't comment
> on the game or the bug, but I'd like to provide a counterpoint
> to this. Keeping your save files in a text format instead of
> a binary format likely only (approximately) multiplies their
> size by a constant. If you simply add a layer of compression
> (e.g. gzip) for release versions, even that effect is almost
> eliminated.

Text compresses very well, that's true. And it's easy to debug.

> I'd say you should keep your save format in the way that's
> easiest to read and write, or most helpful in debugging,
> and then simply it run through compression (at least for
> release versions). Concentrate on writing your game, not on
> writing an optimized save file format.

It is a way, sure. I've nothing against it as long as it's not too
big.

> As for cheating, I really don't think it matters. People
> should play your game without cheating because it's most fun
> without cheating, not because the save file format is hard to
> modify. If it's _not_ most fun to play without cheating, why
> would you want to ruin what fun they _are_ getting out of
> your game?

Agreed. But I'll make my save format hard to modify anyway :D.

> As an example of this in practice, GearHead uses an ASCII
> file format, easily modifiable and even uncompressed. (The
> saved games are large, but I don't think it really bothers
> anyone.)

It all depends on how much space your savefile will occupy. My game
needs around 60kB to store one map layout (no items or monsters, just
the terrain) in an uncompressed format. The overworld will be large
(I'm switching right now to 448x360), and the local maps are 112x90
each, so it's rather big. All maps are permanent. Suppose you visit
only 200 maps - that's 12MB for the terrain. I suppose the monsters
and items might raise this to some 20MB. When compressed, it'll be
around 5MB, which is acceptable (to me - many people might say the
20MB are nothing), and how much would that be in an uncompressed text
file? 100MB, perhaps? I don't enjoy savegames that occupy 100MB...
100MB vs. 5MB is a huge difference.

Anyway, everyone is free to choose th way they save their files and
I've no problem with that. I just expressed my personal preference,
but have no wish to argue about it or criticise other developers'
choices judging them by my own standards. That would be very silly :)

Mingos

perso...@gmail.com

unread,
Apr 4, 2009, 8:18:03 PM4/4/09
to
Thanks for all the responses guys. For my first project I made the
mistake of uploading only to sourceforge, which got no responses, but
now I'm glad that people can help and will remember to post here too
next time :)
For archiving the map files I'd need to do some library research, I
guess I'll get to that.
Also, how exactly do I use eFence?

I'm being a little lazy for the weekend, I'll probably sort out the
class declarations and definitions as well as comment on Monday. When
I do update it, should I make a new topic post? Sorry, new to usenet.

-Jerry

kaw

unread,
Apr 4, 2009, 8:21:00 PM4/4/09
to
On Apr 4, 9:20 pm, Mingos <dominikmarc...@gmail.com> wrote:
> When compressed, it'll be around 5MB, which is acceptable
> (to me - many people might say the 20MB are nothing), and
> how much would that be in an uncompressed text file? 100MB,
> perhaps? I don't enjoy savegames that occupy 100MB...
> 100MB vs. 5MB is a huge difference.

But as you say, (self-similar) text compresses _very_ well. It
doesn't matter that the uncompressed save file might be 100MB,
because at those sizes you keep compression turned on.

In my experience, compressing redundant data once with a good
algorithm tends to yield better results than compressing it with
a bad algorithm and then compressing the output of that properly.
As such, effort spent optimizing the input to a compression
algorithm for literal space efficiency is not effort well spent.

Of course, text isn't always the best solution -- it involves
a lot of string handling, which may or may not be more trouble
than it's worth. This depends heavily on the language and
libraries used. I'm just saying that not wanting to waste disk
space is a poor reason to avoid it, simply because it's based on
a false assumption -- compressed text is not very wasteful
at all in this respect.
-kaw

Mingos

unread,
Apr 4, 2009, 8:25:05 PM4/4/09
to

Of course, I was talking about the disadvantage of UNCOMPRESSED text.

Mingos

Message has been deleted

Mingos

unread,
Apr 4, 2009, 8:42:23 PM4/4/09
to
On 5 Kwi, 02:18, personje...@gmail.com wrote:
> Also, how exactly do I use eFence?

If you are running Ubuntu, install it by typing "apt-get install
efence" (without the quotation marks, obviously). I'm not sure how to
install it on distros that don't use apt. In Mandriva, efence is in
Drak (the RPM manager), so I never even bothered with figuring urpmi
out. No idea about other distros.
Once it is installed, create a build target, for instance "efence"
and
link it with efence (should be in the linker options - just add
"efence"). Then run the debugger. It'll debug using efence and any
buffer/stack overflow will be discovered. If the program causes any
sort of segmentation fault or something, it'll stop and you can check
the call stack to see what triggered the error.
I recommend using efence always when debugging (just link with efence
in your Debug build). In fact, I'd always run the game with efence
until you make a release build.
Mingos

perso...@gmail.com

unread,
Apr 4, 2009, 9:26:37 PM4/4/09
to

Argh. I did it quickly, installed package "electric-fence" (not
efence), added "-lefence" to g++ command line, and here's the result
after running the app and closing it:

jerry@COMPUTER:~$ ./a.out
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
Segmentation fault
jerry@COMPUTER:~$

Mingos

unread,
Apr 4, 2009, 10:24:02 PM4/4/09
to

Good. A SIGSEGV (segmentation fault) means that your program is trying
to access memory outside of the part that was assigned to it. For
instance, this code:

int myArray[10];
for (int i = 0; i <= 10; i++) myArray[i] = i;

will produce a segmentation fault, since it'll try to access myArray
[10] while the max index is 9.

I don't know how you can do that in command line. I use Code::Blocks
and checking the call stack is very easy there. It usually indicates
clearly which line caused the segmentation fault and what function has
been called to produce it, along with the variable value that is
wrong.

Mingos

Martin Read

unread,
Apr 5, 2009, 6:57:27 AM4/5/09
to
perso...@gmail.com wrote:
>jerry@COMPUTER:~$ ./a.out
> Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
>Segmentation fault
>jerry@COMPUTER:~$

Try
gdb ./a.out
and type
run
at the gdb prompt. This will tell you what line your code is crashing
at.
--
\_\/_/ turbulence is certainty turbulence is friction between you and me
\ / every time we try to impose order we create chaos
\/ -- Killing Joke, "Mathematics of Chaos"

perso...@gmail.com

unread,
Apr 5, 2009, 1:02:45 PM4/5/09
to
On Apr 5, 6:57 am, Martin Read <mpr...@chiark.greenend.org.uk> wrote:

Alright, I tried that. It seems that somehow the bug happens only once
per compile (e.g. once I run it once, subsequent runs will not make an
error unless I recompile). Anyway the first time I backtraced it said
that the error was found during the saveTiles() function, but as far
as I can tell the code is sound:

#define HEIGHT 576
#define WIDTH 768
.
.
.
const int GRIDHEIGHT = HEIGHT/TILESIZE;
const int GRIDWIDTH = WIDTH/TILESIZE;
.
.
.
void
Tile gCurLevel[GRIDWIDTH][GRIDHEIGHT]
.
.
.
saveTiles()
{
std::ofstream outfile("tiles.txt");
for(int i = 0; i < GRIDWIDTH; i++)
for (int j = 0; j < GRIDHEIGHT; j++)
{
outfile << gCurLevel[i][j].save();
}
outfile.close();
}

The second I did it, this was the result:
jerry@COMPUTER:~/myrl033109$ gdb a.out
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/
gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run
Starting program: /home/jerry/a.out
[Thread debugging using libthread_db enabled]
[New Thread 0xb77866c0 (LWP 13512)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb77866c0 (LWP 13512)]
0xb7dc5cc3 in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb) backtrace
#0 0xb7dc5cc3 in ?? () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7dc70d7 in ?? () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7dc74b6 in free () from /lib/tls/i686/cmov/libc.so.6
#3 0xb792fc5b in _XimLocalIMFree () from /usr/lib/libX11.so.6
#4 0xb79308fb in ?? () from /usr/lib/libX11.so.6
#5 0xb7912944 in XCloseIM () from /usr/lib/libX11.so.6
#6 0xb8015f8e in ?? () from /usr/lib/libSDL-1.2.so.0
#7 0xb801e930 in ?? () from /usr/lib/libSDL-1.2.so.0
#8 0xb80098f0 in SDL_VideoQuit () from /usr/lib/libSDL-1.2.so.0
#9 0xb7fde465 in SDL_QuitSubSystem () from /usr/lib/libSDL-1.2.so.0
#10 0xb7fde4ee in SDL_Quit () from /usr/lib/libSDL-1.2.so.0
#11 0xb7d84d89 in exit () from /lib/tls/i686/cmov/libc.so.6
#12 0xb7d6c68d in __libc_start_main () from /lib/tls/i686/cmov/libc.so.
6
#13 0x08049271 in _start ()
(gdb)

So the error is in SDL_VideoQuit? What does that mean ?!

perso...@gmail.com

unread,
Apr 5, 2009, 1:18:00 PM4/5/09
to

Alright to clear up. The SDL_VideoQuit bug happens when I compile
WITHOUT -lefence, and it happens EVERYTIME I run the program, not
depending on compile. Basically if you click the 'close' button, the
screen stops updating, but the window does not close. The map becomes
blank if it wasn't so already but the player's position is saved.

With -lefence, and with no previous save files, upon closing the
program segfaults and shows:

(gdb) run
Starting program: /home/jerry/myrl033109/a.out


[Thread debugging using libthread_db enabled]

Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
[New Thread 0xb77579f0 (LWP 14063)]

Program received signal SIGSEGV, Segmentation fault.

[Switching to Thread 0xb77579f0 (LWP 14063)]
0xb7f5275f in std::string::clear () from /usr/lib/libstdc++.so.6
(gdb) backtrace
#0 0xb7f5275f in std::string::clear () from /usr/lib/libstdc++.so.6
#1 0x0804a875 in customItoa ()
#2 0x0804ad82 in Tile::save ()
#3 0x0804affa in saveTiles ()
#4 0xb7d55d89 in exit () from /lib/tls/i686/cmov/libc.so.6
#5 0xb7d3d68d in __libc_start_main () from /lib/tls/i686/cmov/libc.so.
6
#6 0x08049281 in _start ()
(gdb)

Thus here is customItoa:

std::string customItoa(int toconv)
{
static std::string itoatemp;
itoatemp.clear();
itoatemp.insert(0,1,(char) (toconv % 10 + ASCIIZERO));
while (toconv > 10)
{
toconv /= 10;
itoatemp.insert(0,1,(char) (toconv % 10 + ASCIIZERO));
}
return itoatemp;
}

Otherwise if there are save files, the map becomes BLANK (all
walkable, seen) but doesn't segfault and player saving works.

perso...@gmail.com

unread,
Apr 5, 2009, 1:21:27 PM4/5/09
to

Oh jeez I fixed it. I just removed the clear string statement in my
customItoa and changed the static string to a normal string.

Seemed like an extremely strange bug though.

-Jerry

Jilles Tjoelker

unread,
May 2, 2009, 6:56:12 PM5/2/09
to
On Sun, 5 Apr 2009 10:18:00 -0700 (PDT), perso...@gmail.com
<perso...@gmail.com> wrote:
>> jerry@COMPUTER:~/myrl033109$ gdb a.out
>> GNU gdb 6.8-debian
>> Copyright (C) 2008 Free Software Foundation, Inc.
>> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/
>> gpl.html>
>> This is free software: you are free to change and redistribute it.
>> There is NO WARRANTY, to the extent permitted by law.  Type "show
>> copying"
>> and "show warranty" for details.
>> This GDB was configured as "i486-linux-gnu"...
>> (gdb) run
>> Starting program: /home/jerry/a.out
>> [Thread debugging using libthread_db enabled]
>> [New Thread 0xb77866c0 (LWP 13512)]

Threading (e.g. from SDL's thread and timer functions) can easily cause
problems that are very hard to debug, and disappear/appear when you
enable/disable debugging or make other seemingly irrelevant changes.

You may want to use a version control system instead of manually copying
code to directories with dates. My personal favourite is mercurial (also
called hg).

> [Thread debugging using libthread_db enabled]

> Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.

Try using valgrind instead of efence. It will check lots of things while
executing your program; the errors it prints out tend to be fairly close
to the actual problem. You can install it via your distribution.
Documentation is included, or you can go to www.valgrind.org.

> std::string customItoa(int toconv)
> {
> static std::string itoatemp;
> itoatemp.clear();
> itoatemp.insert(0,1,(char) (toconv % 10 + ASCIIZERO));
> while (toconv > 10)
> {
> toconv /= 10;
> itoatemp.insert(0,1,(char) (toconv % 10 + ASCIIZERO));
> }
> return itoatemp;
> }

Because of the static variable, this function may cause problems if
called from multiple threads at once. Removing the static will likely
fix this.

The function also breaks if toconv is negative.

--
Jilles Tjoelker
jilles AT stack DOT nl

perso...@gmail.com

unread,
May 18, 2009, 3:26:51 PM5/18/09
to
On May 2, 6:56 pm, Jilles Tjoelker <jil...@stack.nl> wrote:
> On Sun, 5 Apr 2009 10:18:00 -0700 (PDT), personje...@gmail.com

Thank you, the >10 check might very well explain an odd shading bug.
And yes I am aware of the negative breaking, but seeing as most of the
numbers are unsigned I think it'll be fine.

In addition, this game is meant to run in single thread (I've done
very little multithreading).

Finally, about source control, I was just probably going to keep this
a small project and the only version control I've used is SVN, which I
am still not very familiar with.

Radomir Dopieralski

unread,
May 21, 2009, 5:12:56 PM5/21/09
to
At Mon, 18 May 2009 12:26:51 -0700 (PDT), perso...@gmail.com wrote:

> Finally, about source control, I was just probably going to keep this
> a small project and the only version control I've used is SVN, which I
> am still not very familiar with.

Version control benefits your project no matter how big it is -- it
affects the way you write your code, the way you plan small, atomic,
easy to describe changes, finally the way you just remove dead code
instead of commenting it out "because you might need it" -- if you do,
you just copy it from an earlier revision. It also makes it easier to
review and publish your code, and in the future, to let others help you.

SVN and CVS indeed have large entry barriers, I could never get used to
using a repository until I started using the distributed systems like
Mercurial (very simple to learn), Git or Bzr.

--
Radomir Dopieralski, http://sheep.art.pl

fu

unread,
May 21, 2009, 11:56:11 PM5/21/09
to
On May 21, 5:12 pm, Radomir Dopieralski <n...@sheep.art.pl> wrote:
>
> SVN and CVS indeed have large entry barriers, I could never get used to
> using a repository until I started using the distributed systems like
> Mercurial (very simple to learn), Git or Bzr.

Perforce also has free personal licenses for Windows developers.
Pretty painless to setup and the clients are a bit easier to use when
you're first starting out.

perso...@gmail.com

unread,
Jun 3, 2009, 7:10:01 PM6/3/09
to

ah yes, now i am regretting not using version control as my update
backups are very infrequent, and i seem to have encountered a strange
bug... (in fact I haven't gotten very far from the one posted here)

0 new messages