My tentative title is "Jacob's Matrix". My plan is to use libtcod
this year, so I'll be a bit longer getting the @ on the screen than in
the past. Also because I'm doing a non-cartesian approach to map
generation...
Start time is: 9:25 am EDT, March 8th.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
Non-cartesian? Thinking of using polar co-ordinates...? Or do you
mean non-euclidean, with overlapping rooms like you mentioned before?
(sorry, had to nit-pick)
--
Darren Grey
Cartesian, I think, would be the idea of representing each point with
a unique (x,y) pair.
Instead, each grid cell can be connected arbitrarily to its
neighbours, rather than in a fixed grid pattern. I called this non-
euclidean before. I have no idea which term is better.
(insane amounts of nits to be picked)
Classically, you have the trichotomy of spherical (curvature +1),
euclidean (0) and hyperbolic (-1) planes.
Jeff was referring to the euclidean plane as cartesian. This is not so bad
because the other two geometries cannot be parametrised as such. But of
course flat space does not depend on the choice of coordinates, as Darren
points out.
What is really meant (as I understand it) is that Jeff replaces the
two-dimensional lattice (a doubly-periodic infinite graph) by other
graphs. It is not too unreasonable to call the lattice "cartesian",
because vertices are uniquely encoded by two numbers. (The difference to
cartesian coordinates for the euclidean plane is between discrete and
continuous parameters.)
I think that 'non-lattice graphs' would be pretty precise. Not that this
would have any impact on Jeff's game. Good luck!
David
I knew someone would chirp in with a more detailed analysis ;)
Anyway, yeah, good luck with the game - should be very interesting to
play.
--
Darren Grey
> Instead, each grid cell can be connected arbitrarily to its
> neighbours, rather than in a fixed grid pattern. I called this non-
> euclidean before. I have no idea which term is better.
Technically, any space with obstacles in it is already non-euclidean,
because the euclidean metric stops working in it, and we have to use
patchfinding algorithms instead. So the typical roguelike map is already
non-euclidean, at least for the player and monsters.
But I think we all know what one has in mind when using this term...
--
Radomir Dopieralski, http://sheep.art.pl
Except, of course, roguelikes are littered with DIST(a, b) = MAX(ABS
(),ABS()) type code because we usually use the euclidean metric as a
first approximation. This roguelike requires that I avoid all such
assumptions, which, interestingly enough, makes the code cleaner.
Now it compiles and runs! Still doesn't draw anything to the screen
yet, though :>
Yay! After many hard hours of work I have an @ moving around the
screen. You can also rotate the screen 90 degrees and your controls
remain in screen-space. Portals aren't created yet so there is no map
stitching yet, but theoritically it is in place. Building on top of
SaveScummer's world, so I have monsters and AI all built now.
Oh, the game engine is also running on a separate thread from the
display thread. Hopefully this lets me do timed screen effects
nicely.
Today I've got arbitrary portals linked up so I can stitch my map
fragments together anyway I chose. These portals are transparent to
LOS so there is no distinct stitching to the end user. This can
render dungeons "inconsistent", however, I just rather think of it as
twisty-turny passages, all different.
Portals are now wide. I have the rooms coloured and the jacobian
computed. Tried my first real play through which proved exciting,
which is promising. Going to have to modulate the room generation to
try and make the jacobian more interesting, however. Drew another 10
maps. Ascii-paint makes this a lot easier.
--
Jeff Lait
POWDER:http://www.zincland.com/powder)
SNIP
>
> Portals are now wide. I have the rooms coloured and the jacobian
> computed. Tried my first real play through which proved exciting,
> which is promising. Going to have to modulate the room generation to
> try and make the jacobian more interesting, however. Drew another 10
> maps. Ascii-paint makes this a lot easier.
For map making, I am using the awesome JaVe tool, I recommend it.
--
Slashie
> Portals are now wide. I have the rooms coloured and the jacobian
> computed. Tried my first real play through which proved exciting,
> which is promising. Going to have to modulate the room generation to
> try and make the jacobian more interesting, however. Drew another 10
> maps. Ascii-paint makes this a lot easier.
Fixed the jacobian, I had it wrong after all.
Added flames - don't worry, no performance implication if you have a
quad core or greater.
Created the effect layer so the engine can post display effects like
fireballs, arrows, and flashing colours when hit. This is a bit
complicated because the mapping of positions on the map to positions
on screen is something only known by the display, not the engine, and
the engine is running on a separate thread from the screen so
everything needs to be properly queued. I'm thankful to Python's
Queue class for inspiring my own Queue class. Queues are a nice
primitive to use for multithreading.
Fell behind on room drawing.
Every time you post I get more intrigued by this game. I'm not even
sure I can imagine what it is going to be like. Love the performance
specs, btw.
I just tried running on my Core Solo laptop. I couldn't run it debug
as it was painfully slow. Optimized could chug along but was very
laggy and the fire was choppy. I'm hopeful I can just drop the fire
res for these machines and get something more interactive.
Much more polish done, including the music integration. I am now
hopeful it will be more of a game than a tech demo.
Note: Having ants digging out rooms that have invisible portals
stitching them can result in much confusion. I'm going have to make
certain walls undiggable...
It sounds like you have implemented quite a feature set for a 7drl!
Can't wait to see what you have in store for us :)
-Ido.
A lot of the traditional roguelike features will be identical to Save
Scummer / Letter Hunt, so it has been more about making sure this
content works in this new world than creating new content.
I finally addressed the issue of mobs not pathing through portals
properly. This is, for efficiency, only robust around the avatar, but
I don't care about off screen mobs anyways.
Ants no longer dig in troublesome manners.
Fireballs are fixed. When you have a POSition object you use to
invoke fireball on, it is dangerous to do:
victim->pos().fireball(radius=3)
because the position may be deleted when the victim dies :>
I finally tracked down the crash on quit so hopefully it will seem
more polished :>
I finally played it far enough to reach pythons so, of course, found
lots of issues when they swallow you. While the sudden change in
camera angle as you copy their angle might have been justifiable, the
fact that they'd digest you every second real time (rather than every
turn) was an artifact of my aiForceAction not being called in the
fashion I expected - any of the non-turn commands, such as the "regain
mana" which occurs every second, would trigger another round of
digestion.
First pass at the "portal gun" has been done, looking forward to see
if it has positive gameplay effects.
Now I have one full day left! Hopefully I can concentrate on room
building and polishing the game play more.
Note to self, plural of Shaman is not Shamen.
If you are storing your FOV flag on the map position, but you have
portals that build a hall of mirrors, you will get inconsistent values
for said flag. One approach would be to union the flags, which means
you can see more into a portal than you should, but you could retcon
this as being the player reconstructing what is on the other side
based on what they can already see around them...
Handy to know - I intend to have a hall of mirrors in Gruesome at
eventually, and have been pondering how to implement it without
extreme headaches... :) Looking forward to seeing your release.
--
Darren Grey
I have a sneak peek up. I've got a distribution on the site,
http://www.zincland.com/7drl/jacob
with no live links yet. While it is called jacob7drl.zip, it isn't my
final submission yet. I've got a few more polish issues to do. But
if anyone can manage to report bugs in the narrow window from reading
this to me being able to adjust them prior to sleeping, I'd like to
hear :>
Please note that it is only a Windows release. For some reason I just
get a black screen when I built it under Linux. I think it is the
machine in question not liking the use of the sound card, but I'm not
going to debug it at this point in time :>
For now, check out:
http://www.zincland.com/7drl/jacob
I'm afraid it is windows only. Linux is black screen and refuses to
report key presses.
Very interesting. It almost feels 3d as the portals twist over and around.
Neat concept, good execution.
--
Rick Clark
Clark Productions: http://rickclark58.googlepages.com/
Very intriguing game, as expected ;)
Also I have a few technical issues with it. Some might be libtcod
bugs... :
* first it uses 100% cpu. Are you limiting the framerate with
TCODSystem::setFps ? I don't know how it can fit in the multi-threaded
architecture, though.
* jacob.cfg doesn't seem to be taken into account. I changed the
flames height and tried to set windowed mode but the game it doesn't
do anything. Also I can't switch to windowed mode while in game. The P
shortcut only make the screen blink once, but it stays fullscreen.
I still have to dig it, though, because I didn't figure out everything
and I don't know (or rather don't remember) what a jacobian is... ;)
--
jice
Thank you, very glad to hear it ran for you. What level did you get
to?
--
Jeff Lait
(Jacob's Matrix: http://www.zincland.com/7drl/jacob)
No, I am not limiting the frame rate, so the main display thread will
happily do 100%. However, I had found with another project that if
you have another thread at 100% and try to limit the display thread
you seem to start missing keystrokes. I never did try this with this
project, so it may or may not be effective.
The real killer, however, is the flames. There are two threads
running and it is quite likely they don't get their job done within
the 20ms allotted, so they will each be 100%.
> * jacob.cfg doesn't seem to be taken into account. I changed the
> flames height and tried to set windowed mode but the game it doesn't
> do anything.
Darn... Yes, I can reproduce this with the version I download from
the website. I am very confused as it worked just fine when I tested
it, I wonder if I broke something at the last moment?
Changing the flame size does work. Note that it does not change the
size on screen, it changes the size of the simulation that is then
sampled to draw on the screen. If you set it to 0, for example, you
should get the bars.
> Also I can't switch to windowed mode while in game. The P
> shortcut only make the screen blink once, but it stays fullscreen.
This also doesn't work with the downloaded version, but worked when I
tested. I'm just invoking TCODConsole::setFullScreen() here...
> I still have to dig it, though, because I didn't figure out everything
> and I don't know (or rather don't remember) what a jacobian is... ;)
Glad to hear!
It seems to only show up on the optimized build. However, I think the
serious clue is that I couldn't pass bool down in the first place.
Check this code out:
0040B887 mov eax,dword ptr [glbConfig (41E61Ch)]
0040B88C mov cl,byte ptr [eax+10h]
// The logical thing to do would be to pass fullscreen into here.
// But for reasons I cannot fathom, if I do that it always goes
// full screen even if it is false! Bah.
TCODConsole::initRoot(SCR_WIDTH, SCR_HEIGHT, "Jacob's Matrix",
false);
0040B88F xor ebp,ebp
0040B891 push ebp
0040B892 push offset string "Jacob's Matrix" (41B3F0h)
0040B897 push 32h
0040B899 push 50h
0040B89B mov byte ptr [esp+38h],cl
0040B89F call dword ptr [__imp_TCODConsole::initRoot
(4191F0h)]
TCODConsole::setFullscreen(fullscreen);
0040B8A5 mov edx,dword ptr [esp+38h]
0040B8A9 push edx
0040B8AA call dword ptr [__imp_TCODConsole::setFullscreen
(4191F4h)]
0040B8B0 add esp,14h
You will note that we use cl to store the bool value, suggesting a
short-enum world. When we call setFullscreen we push dword ptr [esp
+38h], of which only the lower byte is 0. If the callee is living in
a full-enum world, the bool enum will be 32 bits, so all the extra
crap will cause it to believe that it should be full screen,
regardless of what the lower 8 bits are. I'm trying to find out how
you built it but I can't find your Makefile/.sln files in the tarball
I have.
Ah... Solved it myself...
The built in C++ bool is a char. This is used in my code, as it is C+
+. libtcod uses an enum { false, true } which, if -fno-short-enums is
set, or in the MSVC world where enums are allows large, will be an
integer. So the MSVC code generator is pushing a bool onto the stack
as that is what TCODConsole::setFullScreen() wants, but then
TCODConsole::setFullscreen() is reading an int off the stack since it
thinks bool is an integer and much zaniness ensues.
Now hopefully I haven't called too many functions that use a bool...
Okay, I managed to build a work around. I had to basically only ever
call the libtcod functions with a constant false or true, only then
would the compiler be lazy enough to not bother to leave the stack
undefined. It actually went out of its way to undefine the stack if
I, for example, just called with an int rather than a bool.
Please fix your C-style bools! They must be char, not int, to match C+
+. Or get rid of bool from the C++ interface.
> Thank you, very glad to hear it ran for you. What level did you get
> to?
I only made it to level two. This is definitely a keeper though, so I'll be
trying it again.
Looks cool, though can be a little confusing to play. Suppose I'll
get the hang of it eventually...
One weird bug though - after quitting it's turned my cursor into
some... thing. Looks like a column of 6 little arrows. Screenshot
doesn't work in capturing it... Dunno what the hell's going on, but
it's weird. Was running it in Windows mode and the cursor had changed
when I exitted the game (which should be easier by the way). Restart
will fix it I'm sure.
By the way, game runs at a steady 75 or so on my quad core. Runs
perfectly fast, and the looks are worth it :)
--
Darren Grey
I am happy to announce it now supports Linux. Yay!
It does twist your mind. Last night I dreamed of coloured dungeons :>
> One weird bug though - after quitting it's turned my cursor into
> some... thing. Looks like a column of 6 little arrows. Screenshot
> doesn't work in capturing it... Dunno what the hell's going on, but
> it's weird. Was running it in Windows mode and the cursor had changed
> when I exitted the game (which should be easier by the way). Restart
> will fix it I'm sure.
Worrying. There is some funkiness because both I and libtcod grab
SDL, and I think libtcod does an atexit() SDLshutdown which crashes if
I don't also pre-shutdown...
> By the way, game runs at a steady 75 or so on my quad core. Runs
> perfectly fast, and the looks are worth it :)
I am happy for your vote of confidence!
>> The built in C++ bool is a char. This is used in my code, as it is C+
>> +. libtcod uses an enum { false, true } which, if -fno-short-enums is
>> set, or in the MSVC world where enums are allows large, will be an
>> integer. So the MSVC code generator is pushing a bool onto the stack
>> as that is what TCODConsole::setFullScreen() wants, but then
>> TCODConsole::setFullscreen() is reading an int off the stack since it
>> thinks bool is an integer and much zaniness ensues.
>
> Okay, I managed to build a work around. I had to basically only ever
> call the libtcod functions with a constant false or true, only then
> would the compiler be lazy enough to not bother to leave the stack
> undefined. It actually went out of its way to undefine the stack if
> I, for example, just called with an int rather than a bool.
>
> Please fix your C-style bools! They must be char, not int, to match C+
> +. Or get rid of bool from the C++ interface.
sizeof(bool) in C++ is implementation defined, and I've certainly seen
compilers with sizeof(bool) == sizeof(int).
To solve this properly, it's important not to confuse the C++ compiler
into thinking "C++ bool" where libtcod actually means a user-defined
type. Renaming the libtcod type would be the cleanest solution to
achieve this.
Cheers,
Malte
Maybe the cleanest, but not the most handy for the end user. Imagine
mixing TCODBool, SDLBool, FMODBool, WhateverBool...
The best for libtcod is to make bool work without complications. I
already spotted this issue some time ago and fixed it in a few places
but not everywhere. By the way, it happens only with Visual Studio...
--
jice
The enum is not used for C++. It's enclosed in ifndef __cplusplus. So
with C++, it uses directly the C++ bool.
Since both the call to setFullscreen in your code and setFullscreen
implementation in libtcod have been compiled with MSVC, they use the
same bool definition.
The problem occurs when the C++ wrappers calls the C implementation,
which uses the enum.
I think replacing bool by int is the C prototypes when the .h are
included by a C++ file will make everything work smoothly.
To be fixed in final 1.4.1...
--
jice