Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

jmlait

30
Posts
68
Followers
A member registered Jan 05, 2018 · View creator page →

Creator of

Recent community posts

Thank you very much, I am happy you enjoyed the writing!

How many turns did you have left when you won?   I was unsure how tight to make that - I suspect defocus is most important in getting turn count down by avoiding encounters and pre-mapping mazes.  I erred on the cautious side as I'd rather people win and treat final turn count as a high score :>

Darn...  Windows in the last few years started to fail to run my old SDL1.2 code with one of the updates :<   This is clearly affected and I need to port to 2.0 and re-release. 

Thank you for trying it!

Drawing a map is certainly an option.  But Shift+C can also be used to visualize your current room without being confused by doors seen afar.

Spells don't last forever - they will fade from your mind, possibly in an inopportune time.  This is why you want to keep the spellbooks around to refresh your memory.  Since there are no magic points, it is the relearning that gates being able spam spells.

Writing sets need something blank to write on.   If you read a book enough times you will get something.  It is also possible to create blank scrolls, but that's complicated.

If you check the ? keyboard list carefully you'll see [q] Quaff or Drink.  This is a way of ingesting potions without soaking your neighbours.

Map visibility is as useful with the map off as on!  You can use [x] to cursor over the map to recall what you had mapped - after using the scroll it is all mapped for you.  [.] while in this mode will report your current location relative to yourself, in case you lose track.

This source code dates from 2005 with my first 7DRL.  Each year I strip it down and build something new.  But the strip down is never complete, so it accumulates a lot of interesting stuff on the way :>  My first 7DRL used curses and SDL1.2 for rendering, I thus built the gfxengine to abstract the two backends of gfx_curses and gfx_sdl.  Around the time of Jacob's Matrix I switched to libtcod as the backend and just folded it into gfxengine.cpp.  For graphics I mostly treat libtcod as a console buffer, however, so almost all logic is outside.  I do use libtcod's FOV algorithm and a few other neat things though.  So not so much any limitations of libtcod as history...

The most game-related files, as opposed to generic, are likely:

ai.cpp; builder.cpp; item.cpp; main.cpp; map.cpp; mob.cpp; source.txt; text.txt

Good luck in your next attempt!

The 7drl one can be whatever is in your 168 hour window.  So if you get a second build within the 168 hour window, feel free to replace the previous upload.

We request you maintain a 7DRL version of your game for reference.  People judging may elect to play either that one or  the latest.  Change notes can specify what was fixed / added so the judges can take that into account even if they play the latest version.

You can direct people to the latest & best version, however, as we'd want the normal players of your game to have the best experience as possible.

We intentionally semi-blind the review process.  This can be frustrating if they clearly missed some component.  OTOH, this is pretty good feedback to know what impressions are without the chance to clarify.  Most who play will not get the chance to debate the point :>

As for the second reviewer, if I were you I'd not readily conclude that they missed the procedural nature of your level generation.   Procedural level generation is neither necessary nor sufficient to make something a Roguelike.  It is hard for a platform, especially an abstract one, to get beyond "Roguelite".  And for many players out there, even achieving that level is questionable.

Using a real-time speed run approach is very non-roguelike - this undermines the tactical nature of roguelikes making it more twitch play.  I know with Jacob's Matrix I found that merely adding a wall-clock timelimit to a turn-based game completely changes *how* you play it.   The mechanics of Jacob's Matrix are extremely roguelike; but in practice it doesn't feel much like one.

Awesome!  Thank you!

Very cool!  I really regret not having a mac build.  Can you please put the changes on git hub?

Well, I take issue with the statement "like most games"; as if continuous time were the natural default choice in ludological circles; and turn-base some form of exception that requires distinction. :>

Everyone is welcome to explore the boundaries of roguelikes, so the answer is going to be "yes" regardless of what the question is.  The spirit requests that you, yourself, are in the spirit of "roguelike", and you are the only one that knows if that is true.   (It is like Nanowrimo, when someone asks if they can submit 50,000 words of "a".  Yes, you can.  But why?)

As for the issue if discrete time is a requirement for roguelikes?  I personally do not believe so.  I think, however, it is a natural consequence of roguelikes.  Anytime you start to build a tactically focused game, you naturally move to discretization of space and time.  (And of health, esp when taken to the 1hp extreme)

Chess isn't played by turn on a grid because of limitations of a ASCII terminal or lack of continuous input modality.  (My most interesting example of chess is that within Ultima Online.  Chess there was implemented as merely tokens and graphics of a board.  The two players, like with the real world chess, can place pieces where they desire, and at any time, with no space discretization or time discretization present.  But naturally, just like a real-world chess (which plays in a continuous space) one would play it in a discrete manner to enjoy the game.)

One interesting game to look at if you are thinking of continuous time is https://en.wikipedia.org/wiki/Dungeon_Master_(video_game) .  This is a discrete spatial game with a continuous time model.  From a modern perspective one could argue that it is ... broken .. because of it, but it is a very interesting example that we rarely look at.  (Note this is different from time-expiry turn based, like the old Ultimas, or global wall-clock limits, like Jacob's Matrix, as those will alter the world heartbeat to the turns)

Absolutely!

However, *TEMPER* your expectations.  An impressive success for a new developer is the @ - on - a map level of contribution.  Focus on making the absolutely minimal viable game first.   You need extremely few mechanics to have a fun roguelike (especially if you make it yourself, and play it yourself!)  When you get a simple "wander on a random map, smash monsters without being smashed first" game play done; it is time to start layering on the design.  You can keep this up after the 7DRL - for the 7DRL, get the bare bones walking.   It is incredibly important you can play your game yourself early - this is the motivation that keeps you going.  Don't worry about your own spin.  Make it beige-basic.

After a few months, you'll end with a huge ball of mud and realize you should have planned properly in the first place.  So you'll throw it away and start over again and plan properly with engineering principles you learned.  You'll design very detailed documents of how everything should work; and begin on a proper "clean" design.   This will then fail with you never actually getting an @ to walk on a map as you were too busy writing PerambulationFactories to get any actual real code done.

Then, after throwing away the over engineered system that got nowhere; and the under engineered prototype that got tangled up in its own bootlaces; you'll be ready to tread the middle ground :>

Cf. https://en.wikipedia.org/wiki/Second-system_effect

My main complaint is too many people lead people to their second system first.  Your first system should be the ball of mud that gives you positive feedback.  If your first system is the bloated over-engineered system, it is really hard to have the desire to keep going.

Part of the inspiration of 7DRL is to explore where the boundary between "Roguelike" and "Roguelite" exists.

A specific game cares not for genre; it should always be made the best it can without worrying about labels.

All that said, Roguelike is in the title of the challenge for a reason.  This is not meant to be a complete free-for-all; your polestars should have "Rogue" somewhere in the mix.

Thank you for your interest!  The best way to start is KISS: Keep it simple, stupid :>

The apparently natural manner I'm using in 1812 is very simple.  You can find the details in builder.cpp.  Look for the buildWilderness() function.

The 1812 map has the overmap, and each tile of the overmap corresponds to a large submap.  buildWildreness() builds one of these submaps.  Each square in the submap is populated with merely a 

    set(x, y, weight.pickRandom());

where the pickRandom picks tree, bush, grass, dirt at random according to a weighted distribution.  Now, if each submap had its own distribution, there'd be a harsh line between submaps when you are at the local level.  To avoid that, the weights of each submap (that comes from the chosen overland symbol for that submap) is averaged to the corners of the submaps.  Then each submap linearly interpolates the corner values within itself - that is that weight averaging you see in buildWilderness.

So the heart is very simple - spatially-independent weighted selection.  The two next bits are important: how to generate the overmap; and how to set the weights.

The weights are setup in the source.txt, which is a grab bag for all my declarative constants.  Deep in this you'll find DEFINE TERRAIN, followed by the weights for each type of terrain.  

TERRAIN PLAINS
{
    tile GRASS

    grass 90
    bush 10
    sightrange 100
    armyrange 500
}

TERRAIN BUSHES
{
    tile BUSH

    grass 10
    bush 90
    sightrange 40
    armyrange 300
}

TERRAIN FOREST
{
    tile FOREST

    tree 90
    bush 10
    sightrange 15
    armyrange 100
}

TERRAIN WASTE
{
    tile DIRT

    dirt 90
    grass 10
    sightrange 130
    armyrange 600
}

My setup here was simple - I had a sort of hierarchy of terrain in mind, of what valid things are.  The usual ecological cycle in my part of the world is pond -> meadow -> bush -> forest -> pond, so thus that natural grass/bush/forest transition order.

So then comes the question of the overmap.  This you can find in the buildOvermap function in builder.cpp.  This works at the very coarse level, as we are just picking the overmap terrain type.  The system is a simple randomized markov chain on each tile.  However, the probability tables are controlled by the surrounding tiles.

There are two transition tables used, one in the grow bushes, the second in grow forests.  You'll note a comment about GS - that is Gauss-Seidel.  Since we are processing the tiles in a fixed order, you'll get strong biases as the next tile will see the updated values for its upper left neighbours, and the old values for lower right.  Ideally you randomize sweep orders to avoid this, but I was lazy and instead relied on the fact the noise in the transition rules to hide this.  (Noise hides many sins!)

The exact nature of these rules was heuristic, and derived by just generating and tweaking until I liked the results.  The second pass grow forest, IIRC, was added to try and consolidate the forest networks as otherwise it looked too patchy.

....

But back to your question: Where to start?

Make it easy to experiment.  Setup a test harness so you can see your full level, hit a key, see another one, and repeat.  Seeing a few hundred is a great way to get a sense of what your algorithm is doing and how to tweak it.  Try to keep your level generation stuff high level so you aren't messing around with pointers and edge-cases when writing stuff.  In particular, stuff like indexing your map out of bounds should silently *work* usually, because then a lot of this code becomes easier to read.  It is also useful to separate the "Dressing" from the "Bones".  Ie, often you can just do a 25% replacement of tile X with tile Y at random to break things up.  But this can be a post-process, and the earlier stages can just work with tile X.  That builder.cpp has a lot of other random algorithms in it as I've built them across many 7DRL, so I'd encourage reading them and seeing how they work.

I spent a significant amount of time in optimization for this 7DRL.  I could afford more at this point.  The biggest bottlenecks right now:

1) Copying the soldiers from frame to frame.  This could be vastly accelerated if I switched to a SOA rather than the current pointer-chasing format for the MOB class.

2) Registering bullets on the display.  I already restrict this to only the current FOV, but there is an ugly O(n^2) for my event class that wasn't a problem since normally only have a dozen events per frame at most :>

The big problem is I feel it already runs a bit slow even on high end machines... The simulation is currently completely uncapped (so if we ever get faster machines some day, it will be stupidly fast :>)  I'd have much rather if I could have simulated way faster so given you a 1x, 10x, 60x realtime options rather than the current all or nothing.

Thank you,  I enjoyed the video!  It is always so instructive to see people play something for the first time.

My only serious pain point was that I failed to make clear you can move the telescope even when zoomed in - this lets you frame those big battles so you see both halves, rather than jumping in & out.  (The musket range is actually adjusted to ensure you can see both sides :>)

I very much enjoyed your reaction to regiment 7's decision to charge the foe.  That is very much the thesis of this entire game.

You are correct it is entirely turn based at heart.  Their is a turn-by-turn order and square-by-square movement.  But I'd actually disagree strongly that turn based has anything to do with being a roguelike.  It is more like how perma-death appears a roguelike feature; not because it is a feature, but because a more essential requirement almost forces that decision.

"Permanent Consequences", or "No Save and Continue" are the cause of Permadeath and Random environment.  If you let people screw up permanently, you have to put then out of the misery and restart.  And if you keep restarting, you need the start to be interesting,

Tactical game play is what induces the Turn-based, Grid-based, and Non-modal characteristics.  It is very hard to focus on tactics with free movement or real time.  War of 1812 aggressively removes all tactics from the equation as your level of control is too coarse, leaving it with only strategy.  (And how much strategy there is can be debated.  My interpretation of Tolstoy's argument in War & Peace is that there is no actual strategy in the Napoleonic wars)

Totally agree about the UI complaints.  So much of my 7DRL time is spent on polishing UX, and there is always so many more things I could have done!

Thank you!   Very glad you enjoyed it.  I'm also pretty pleased with the result, even though in my imagination there were a lot of other scope that ended up not being accomplished :>   It also very much is something that likely falls out of the definition of "roguelike" (which is fine for me, as finding these boundaries is what I do 7DRLs for :>)

Well, the gigantic room would be 10,000 x 10,000.  Which means storing just a single byte tile value is 100MB!  And storing a single byte flag value is another 100MB!  To make things more interesting, the UI drawing is decoupled from the actual game engine.  So I have to make a copy of the map every update so the UI drawing thread can read the map without fear of it changing while it is reading.  (The alternative is to lock all reads of the map, which would defeat threading entirely and be atrociously slow)  Copying 100MB is a substantial time.  By breaking into 100x100 rooms, each of a more manageable 10KB size, I can use reference counting to only copy sections that changes.  So stuff like FOV flags are only set on the live rooms - the rest of the rooms just have a flag stating that their FOV flag is constant.  The same is for the smoke simulation - I have to store the amount of smoke per tile, but for the vast majority this is zero, so I can have that allocated only where necessary.

Separate rooms is also a very useful optimization for things like MOB look up. Until 1812 I stored monster and item lists per-room.  Usually rooms were small, so to see if an item was on a square it would be faster to look through all monsters to see if a monster was there than track it per square.  (This particularly relevant for stuff like Everything is Fodder which is technically an infinite map as it generates rooms on demand)  For 1812, I had to build a separate VDB-style (https://github.com/AcademySoftwareFoundation/openvdb) acceleration structure to swiftly locate all creatures globally.  I ended up with separate tables for both teams and for the officers, so I could do efficient searches for all enemy troops, or all friendly officers.

Separate rooms is a very useful roguelike construction technique as you can piece together "levels" that are usually connected by staircases smoothly.  Vicious Orcs is a good example of this.   The original motivation was Jacob's Matrix where it was just to confuse people through non-cartesian coordinates.  And I assure you, it can be very confusing :>

Ah, true, moving multiple units is a pain.  My original plan was for you to setup formations so you could join multiple regiments together as one unit for the purpose of commanding.  This is pretty much how the AI general works.

My other roguelikes can be found on the http://www.zincland.com on the list of 7DRLs there with every increasing adjectives.  I foolishly didn't provide any links on my itch.io profile :>  I keep meaning some day to recompile them all so they can all be also hosted here.

Thank you!   I did try to optimize the controls.  Most importantly, pressing shift and directions lets you move 5 squares at a time, otherwise it gets very painful to move about.  Ideally it would be a mouse-driven interface, but I didn't have time to build that on top.  (Not to mention mice have always felt out-of-spirit for roguelikes to me :>)

What were the aspects of the controls that made it most tedious for you?

I've made lots of 7DRLs, none of which have been epic combat :>  But they definitely laid the ground work to achieve this.  Notably Smart Kobold had huge work for dealing with solving the problem of having densely packed groups of mobs move in a turn-by-turn fashion, but not get all broken up.  Basically they are able to both delay their turn to see if others will move out of their requested spot, and have a priority scheme for shoving other mobs.  And Jacob's Matrix is where I developed the whole non-cartesian coordinate system that lets me stitch 100x100 "rooms" each with 100x100 tiles together in a fashion seamless to the AI and map code.

Source is all there (and BSD) if you want to look at it for your own epic combat game!

Thank you for catching that!  I sent the text.txt through  a spell checker, but that flavour text was inlined in the C++ so escaped detection!

The spell of death works more like the Angband Potion of Death; so it does not make it a complete gamble.

I have no idea how subscriptions work, but at least if I reply you should be pinged!

I'm afraid I had to ship without it due to Windows defender being over-active.  I have got a build that passes locally, so fingers crossed, I may get out a windows release soon!

You should have seen the earlier versions before I started toning down the terrain!  I had bright green for everything, and * for bushes.

A good point though, I really should have pushed the terrain way down, and then brought it back until it looked good.

Very glad you enjoyed it!

ASCII actually helps, I think.  If you try and have a 100x100 grid of fancy graphics it becomes mush.  To fit that number of tiles on the screen you need to go symbolic. And most people have highly trained symbol-recognition systems for ASCII.

Thank you for posting of your experience!

No need to apologize for the incomplete project.   If you never fail, you aren't trying hard enough.  As you reflect in your analysis, the exercise is good.  There is no such thing as a wasted push-up.

I totally agree with the tendency for technical issues to overwhelm game design issues.  I don't want to think how many hours I spent this week trying to fix key-repeat issues with libtcod.

My planning process:

1) Identify the core minimal product that would achieve my vision.   You want this done as early as possible.  When it is done; it is playtesting & refinement.

2) Identify riskiest tech stopping your minimal product, and address that first.

So if physics based path finding was a pre-req for your game design idea, you really did nothing wrong for planning.  If the game design could have worked with crappy path finding?  Then better planning would have focused on other tech first.

But I feel for your path finding pain.  I was lucky my Smart Kobold systems got me pretty close; it was more about finding proper tie breaker rules than any base tech.

Linux binaries only for now.  Source builds on windows and linux.

Unfortunately it is seems my coding style flags Windows Defender, so I had to delay a windows release until I get a build MS is happy with.

In this you can see me go on length about the Importance, and Unimportance, of the Berlin Interpretation.

Part of the 7DRL process is to find out what roguelikes are.  The review process people will be judging your "roguelikeness" from 1-3.  But we don't tell people what those criteria should be. 

But keep in mind players of your game will be expecting a "roguelike", so you should try to stay in their expectations so as to not result in disappointment.

Do be careful, however, as your region may be switching daylight savings during the challenge!   It is 168 wall-clock hours from your start; so if you start 1PM Sunday 3rd, you might be able to legally finish 2PM Sunday the 10th.

Likewise, if you are going to fly across the world do not adjust your personal countdown for the time change :>

7-day Challenge Inception!  Superhot was made for the 7day FPS challenge, so it is quite fitting to see this on the 7DRL!

Very cool!  I appreciate that you make it clear this is improving an existing game. 

Can you please provide a link to a version of the game prior to the 7DRL challenge for the purpose of judging?  Another download file here of the pre-7drl verson would probably be simplest.

I don't begrudge a Star Destroyer for being a mere kit-bashing of pre-existing models.

Re-use code, art, text, everything.  The purpose of the challenge is the creation of interesting new roguelikes.  The easiest route to this is often the vivisection of an existing roguelike :>  Also consider things like libtcod which make A* a mere library call.

As for prior work, the goal is to not write any code; or any text; or any art; *for* your specific planned game prior to your chosen start date.  This is an enforced brain-storming time to turn over ideas in your head or paper and plan stuff out.  So feel free to write down your ideas or paint concept art, just not as code or final sprites :> Do be careful your scope does not get too large...  I'd also recommend doing some adminstrative checks before the start.  Make sure your compiler exists, version control is working, etc.

The purpose of the 7 day window isn't actually to prove some macho ability to code quickly.  7 days is too long for that, IMHO.  It is more like the NaNoWriMo month time limit - it is short in order to drive you to actually complete a game.  Prior to the 7DRL challenge, way too many roguelikes would flounder in a half-baked dream state; wishing to some day be a NetHack but never actually getting to the "game" part.    With a 7 day window you have to just do it; and must not procrastinate or let dreams pile on dreams.

So have fun and good luck!  And feel free to copy & paste your A* code :>