January 2017 Game Dev: 2D PCG ARPG

I successfully integrated my map generator into my prototype.

I now have procedurally generated terrain that link cells on a cartisian plane.



Moving across 3 rooms, top to bottom

The generated map is 500x500 units, with each unit representing a 5x5 tile play area.
Each room is 50x25 tiles, referencing 10x5 units, giving a randomly generated Island up to 50x100 rooms across.
upto 5000 generated unique locations / playthrough.

Since I can now spawn distinct area types (each room is made of 10x5 cells parsed from the map matrix) I should be able to have objects (Terrain obsticles and enemeis) to start generating on room loading based on what terrain tile they are standing on.

IE, scanning tiles Left-to-right, Top-to-bottom, referencing the terrain type (On colour assignment event) with a random function giving the possibility of spawning an object.

Edit: 20 screens down from where I started, I finally reached a beach.

1 Like

I find this awe-inspiring in a very minecraftian/terrarian way. This. Is. Amazing.

Basic object spawning is in place.

On loading an area, the map tiles are scanned and 2 random numbers are selected.
Associated to each terrain type there are probability thresholds for spawning a wall or monster respectively as well reference to what type (IE, in forrest: Tree trunks are spawned while in rocky areas bolders)

For the moment on area transitions the object lists are purged and regenerated on return, so I guess the next step would be to shift these objects into storage to be recalled on revisitng an area

Originally set the thesholds a little too low:

for the moment, monsters spawn in forest areas at a far greater rate than anywhere else.
Followed by rocky areas with an occasional spawn on open grassland.
They do not spawn at all on ocean or beach.

Edit:
And apply dynamic colour variation to terrain tiles to give ground texture.

1 Like

I would like you to be the lead on this since you have done excellent so far (mashaAllah tabarakallah) and I am regretfully not even present yet.

Do you have a WBS / todo-list / something on GitHub? I would like to start by contributing experimental gamepad support. (For selfish reasons which you already know.)

Can we fork/transfer this repo to the MG group?

I plan to go full-force on this and start carrying my weight, inshaAllah. I also would like to introduce you to some readability/style things to make your code more maintainable inshaAllah, as well as some object-oriented concepts.

I forked your code and got it to recognize gamepad keys. I have reverse-engineered your bitflags thing (1/2/4/8) for directional controls, and opened a pull request with gamepad support. If you like it, merge it in.

Salams,

So Iā€™ve been working with your code for a few weeks now. If I may, I would like to suggest some overall changes that will make it more readable/maintainable/extensible. Take this as you may, as little or as much as you like.

  • Try to avoid copy-paste. Copy-paste often introduces bugs because you fix one copy but donā€™t know or forget about the others. Instead, refactor into reusable methods (perhaps with parameters).
  • Avoid magic constants, like the 180 in if(Math.random()*180<=acc) or 10, 10 in player.js. Itā€™s hard to tell what this number represents. Replace it with a constant somewhere, so it has a name (and we can change it in only one place, to change it everywhere). Better yet, create a config.json value.
  • Try to centralize variables (eg. use Game.map_grid.width instead of 50). It makes it easy to change stuff and everything ā€œjust works.ā€
  • Please add spaces after any operator (,, /, *, brackets, etc.). It makes it more readable.
  • Please use semicolons at the end of JS statements. The interpreter can get confused if you donā€™t do this.

Finally, I think your map generator was awesome, and your game idea was awesome, but they donā€™t play well together. 25x50 is way too huge a game map to even begin to understand (especially with no mini-map).

Honestly, I would suggest severely nerf (or back out) the map generation change and go back to the simpler version, and slowly generate only what you need there.

The game takes about 15-20 seconds to boot on my decent dev box. Iā€™m sure thereā€™s room for optimization; but again, a smaller, less complex generation + map, would solve this.

I know you like to build cool stuff, and honestly mashaAllah tabarakallah you built something really awesome here. I just donā€™t think it fits in the game or makes a great game necessarily (at least, not one we can finish in the next month).

We need a theme, goal, and challenge/difficulty for this game. I can put my PM hat on if you want and lead that side of the project. Do you want me to do that? What ideas do you have so far?

Salaam bro,

Sorry I have been out of contact a few days but work has been fairly heavy again (Just had an 11 hour day fixing our database and patching our website). A project we have is having difficulties and I am trying to mitigate how much problem and political fallout we will have when the hammer drops on mondayā€¦ Sadly only so much I can do when the company keeps passing the dev work to the cheepest contractors in china instead of giving our in-house team any time or resources. We are also running our servers out of a cupboard on the worlds slowest internet rather than using a real data center, so that canā€™t be helping things eitherā€¦

Anyway, the code you pulled from the repository is a version behind what I am working on, and I am midway though prototyping some new code so it isnā€™t in a state for me to push just yet. I wasnā€™t expecting to share this code much when I started working on it as I thought this would be a play around prototype to learn the language before we start working on the protptype proper, so I have just used a variable naming convention that is comfortable for me rather than one others will understand because I really could not be bothered writting out long variable names when 2-3 characters tell me what it is in a way that is easier to type.

The code will need a heap of revision if it is to become our group project.

The map generator was written when I was playing around with ideas for a migration based game and was included in the ARPG code as a curiosity and liked how it looked. I agree that the map is too large and ultimately featureless as a game unless we start inserting some pre-made assets like destinations randomly placed around it and either make it smaller or add some sort of navigation to points of intrest.

My original idea for this before I wrote the map generator was essentially an array of rectangle rooms populated by walls and enemies, sort of in the style of early zelda and Binding of Issac.

I am thinking that maybe we should use the map generator as an overworld and going back to the original multi-room dungeon idea for actual gameplay at the placed locations.

Waā€™alikum as-salaam,

No worries ā€“ I keep chugging along. That works well.

Yeah, letā€™s decide what to do with this. If you want to scale it down or pull the map generation out entirely, thatā€™s reasonable too.

I saw something interesting with Dajjalā€™s Minions: I only had to tweak the guns settings. They were 95% of the way there, but that 5% made a huge difference in terms of fun (practical, usable weapons). I will try to keep that in mind going forward.

Iā€™m not a fan of huge rewritings of code, I prefer to soldier on ā€“ itā€™s a judgement call when to do it.

Lets scale the map down.

200x200 sounds workable. If you want to keep an Island shape then you will need to scale back the numbner of iterations in the 1st nested loop that generates the land mass.

The number of Rock clusters and forests should automatically scale with the land size, dropping those iterations down will lower the size of the generated forests.

I want to try writing a function to make procedurally generated dungeons.

It would be cool if we had the overworld populated with ruin locations leading to dungeons (Like the original zelda) where the player has to get in, explore, find something then escape.

Before I played around with world gen, the idea I had in my head was of a stealth based top-down adventure game set in an abandoned building or crypt. The player wakes up there and has to escape, finding keys and tools along the way to open access to new areas trying to find a way out. The enemies being Jinn or something similar constantly hunting the player. Rarely littered around the place are prayer rooms the Jinn will not enter, acting as safe rooms for the player to reach between sections (Maybe acting as save points).

I still like the idea of having gameplay stealth focused requiring the player to avoid enemies rather than engadging (To be honest, I am rather bored with the idea of combat focused games as that is pretty much every over game ever made).

For the moment I am prototying a map transition. Either in the style of the original zelda:

  • Have a 2nd set of tile objects which on transition, assume the colouration of the new map
  • Place the 2nd set of tile objects in a grid in the direction the map with transition
  • Have every tile object move (Tween) from the direction the player is moving, so the whole map slides from 1 area to the next.

Or alternatively, having these tiles form a single row or colum and having the the map transition tile by tile with the map rolling underneath the player movements rather than discrete areas.
This would need the player to always be more or less centered (Maybe some freedom of movement around the center and the map moves along with the player when they reach 1/3 of the way.

Please merge my PR. There are some good changes in there.

I like the stealth jinn idea. I also still think that the world map generation is the wrong tool for this project. Itā€™s really fantastic, but it doesnā€™t fit here.

Your call ā€“ youā€™re the lead on this one. I just follow orders o7

I am in agreement.
I had more fun playing the the v1 prototype with the simple room than the current implementation.

The map gen was made for a different project out of idle curiosity, rather than made for this specifically.
It event started life as a new project that was then imported into this. Remove it from the current project and I will look at adding it into something else.

Procedually generated dungeon/building all the way.
I have some mechanical ideas in my head that I would like to try, but I am not sure how toā€¦

Edit: Difficult to write with my son running around, He is taking a nap now so i can finally post, but I must be brief.

The Idea I now have in my head I am tentitively calling ā€˜House of Jinnā€™.
It is set in a large procedually generated house (I have an idea for map-gen that I would like to quickly prototype) where the player wakes in a bedroom with no idea of how he got there. The house is dark and seemingly abandoned.

A Jinn is roaming the house searching for the player, the player must move around the house avoiding it and hiding while searching for keys/tools to help him escape.

Throughout the game the player finds pages of a journal that detail the life of the houses owner and the choices he made in his life that caused him to lose everything and empower the Jinn in his home to become so strong.

What do you think?

We already have player movement + collsion.
If I work on game mechanics like map-gen + AI, could you focus on story and objectives?

What I am imagining as far as interface goes, we have what we basically have now with the squares and tiles, but add a section below screen for a point-and-click style inv.

  • Player clicks on objects:
  • Left click to examine - Popup window with flavor text?
  • Right click to interact
    • Bed - Hide under
    • Door - Open (if player has key)
    • Cupboard - Hide inside
    • Collectable - collect

The game draws only the room you are in and outlines of rooms you have been to previously.
Enemy is only drawn when it is in the same room as you, outwise the only way to know how far they are is to listen for their movement to know when they are getting close, and possibly about to enter your room.

AI is to wander from room to room at random, but performing actions that make noise (Moving faster, interacting with objects) while the enemy is in a neighbouring room may attract them to investigate.

oh noā€¦ he is awake againā€¦ I must goā€¦
ā€¦so so wingy lately.

1 Like

Iā€™m only on story and objective? :confused: o7

I really like your working title ā€œHouse of Jinn,ā€ and the overall game idea seems right proper. However, I wonder if it will actually be fun or not ā€“ youā€™re basically running from room to room, randomly fast-clicking stuff to try and figure out interactions before jinni boy shows up.

Letā€™s prototype it. I made a CraftyJS library specifically for prototyping. I am concerned: I remember CraftyJS workflows were typically something like:

  • Get 80% of your game done in 20% of what you thought it would take
  • Get another 15% done with 50% of what you thought it would take (polishing, images, etc.)
    Spend 105% tracking down obscure or browser-specific bugs , reporting them on GitHub, and trying to make sense of what to do when the response is ā€œyouā€™re not using entities correctlyā€

Weā€™ll see. For now, Iā€™ll create a new repo under the MG org, copy/paste the prototyping code and sample HTML, and we can take it from there ā€¦ Iā€™ll create a WBS in an issue.

Sound good?

BTW, CraftyJS is far, far superior as far as ODroid C2 goes, compared to Pyglet.

  • Pyglet detected my controller but no arrows/thumbsticks/buttons work
  • Audio segfaults within ~15 bullet shots

CraftyJS worked like a charm out-of-the-box with F310 and audio has no issues.

Just sayinā€™. Full-screen support is very important to me (the CraftyJS asteroids demo does it) as is F310 support, but I can patch those in after the game inshaAllah if thatā€™s a problem for our very late schedule (Jan 21-22 already, we have barely a month if you look at your vacation.)


Iā€™ve created the repo here. It has full-screen support, and gamepad support, out of the box. Sorry if you donā€™t like it. It also expects an external.json file, like our old config.json file, except you can override parameters on the URL (more on that later inshaAllah).

MVP WBS will show up here.

Also forgot to mention: while I donā€™t like anti-heros, I like the idea of cognitive dissonance. In this context, the player can be doing seemingly ā€œgoodā€ actions after memory loss; as they recover more and more journals, they discover what a vicious, cruel, and evil person they were.

Also, I like the idea of tentative quests/goals/levels/something with ā€œone journal page per whateverā€ as the goal. So itā€™s directed, eg. you have to solve seven rooms, and each gets you a journal page. What do you think?

PM hat is on and we have lift-off.

Link please? I stopped using semicolons a long time ago and havenā€™t gotten into anytrouble except when minifying files. In which case, just start the file with a semicolon and bam, youā€™re good to go.

Probably something like this: http://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascript

Iā€™m pretty sure thatā€™s no longer an issue. I read a similar question a few months ago which didnā€™t state the problem of a function taking another function as an arg. The case for semicolons now isnā€™t as strong as it used to be.

I need to try this!

@Wulf Sorry, Iā€™m not interested in debating it, or in derailing the PCG thread for it. We can discuss it separately. I found it confusing and hard to read, and I remember reading about some cases where interpreters get confused, and it is mostly the industry standard.

You probably have more JS experience than me anyway! I prefer CoffeeScript, which hides you from some of the common gotchas of JS, plus has a nice, Ruby/Python like syntax.

@Severok I did some brainstorming. Based on real (and perceived) jinn stories that I know from reliable sources, I came up with a few general plot ideas (below). I would also like my 8yo to play this, and Iā€™m not sure how to make it ā€œkid-friendly,ā€ but I guess he wonā€™t read most of the story anyway.

  1. The player IS the murdering psychopath who killed his family etc. It started out with the jinn approaching him and saying ā€œIā€™m enslaved since the time of Sulaymaan (alayhi salaam) (which is not true), I can do goodā€ and ended with him committing atrocities and murder and becoming enslaved to the jinn.

  2. The manor used to be the estate of a magician/satanist/hindu/polytheist (insert religion of choice), and hence was very ā€œjinn friendly.ā€ It attracted a particularly nasty passer-by, who happens to haunt it and cause harm to those who enter (much like the jinns who pose as ghosts). It probably coshed our player over the head with a rather blunt object (like a big piece of furniture), causing amnesia.

  3. The house had Muslim jinns in it. One day, the owner was throwing out boiling water or something ridiculous; didnā€™t say ā€œbismillahā€ (hadith: it creates a veil between you and them) and ended up scalding the jinnā€™s kid. Hence, the mom got extremely angry and possessed the manor owner (out of rage). I think heā€™s dead now.

  4. A world-famous shaykh used to teach here. His students came from every part of the earth; he didnā€™t realize, but he had jinn students, too. After his death, they considered his manor something of a sacred property, and forbid people from staying there. (If anyone ever sleeps inside, they wake up the next morning outside). And thereā€™s a room thatā€™s locked, and even with the key, the door is stuck, it just wonā€™t open ā€¦

Sorry if these are all murder-mystery type things. I wrote ā€œhouseā€ and then wrote ā€œmanorā€ and it makes me think of Sleuth, an excellent DOS detective game (which I tried to remake twice).

Thatā€™s all I have right now. Is one of these (or a blend, or something else) acceptable or shall I continue to brainstorm?


@AbrarSyed as discussed, inshaAllah I will ping you with a small task per week ā€“ probably once the initial prototyping is done (by Severok) and we know what weā€™re doing.


Check my branch. I added a simple four-wall mansion that you start in.

Try running the game, then append ?wall_thickness=32 to the URL and see what happens. This is the new config.json (see external.json).

Assalaamu 'alikum dear team lead,

I hope the hammer fell and you are well, and you will rise from the ashes inshaAllah (pun not intended).

I found myself mentally blocked room generation (knowing you would rip out my code later) so instead I moved forward: you now get a simple 2x2 room mansion. That enabled me to make doors, walls with doors in the middle, locked doors, and keys walhamdulillah.

Itā€™s ugly, but it works: grey doors, gold locked doors, gold key. (Looks. Like. Pong.)

Keys are generic: any key for any locked door (no colour-coded keys/doors). The player also has a count of keys.

I donā€™t know if you know this, but you can use Developer Tools/Console (CTRL+SHIFT+E I think in Chrome) and ā€¦ do awesome stuff. Like:

  • `Crafty(ā€œPlayerā€) // get the player object
  • Crafty.e("Door").lock() // create a locked door
  • And so on

I used this to create a second door and make sure the keys depleted correctly.

Standing by for orders ā€“ I will continue work on the WBS inshaAllah in your absence. I also really hope you can leverage my WallWithDoor entity to quickly assemble a working mansion.

Cool stuff.

Sorry again for my lack of activity. It feels like days since I have been able to sit at my laptop.

Insha Allah I can upload some code soon as I am quite frankly getting quiet embarrased by my lack of contribution lately.

Indeed I am slowly working on room generation. I will grab your code so I can see how you are handling the drawing, ect to Insha Allah intergrate my code with yours. Your walls and doors look cool. If I can define a room in terms of Width/Height, possibly with a datum (X-Y point of origin) then Insha Allah it will integrate fairly easily with what I am planning.
I would like to have the current room in the center of the screen with an outline of the neighbouring room attached to each door.

For the sake of making a feeling of claustrophobia and suspense, I would like to only render the contents of the current room so the player is never sure what might be in the next room over until they move there.

What I am working on is tree based layout generation.
I have an object class describing the definition of a room and subclasses for room types.
Room types describe dimension and what rooms can be connected to it as a child.

EG:

  • Enterance connects with: Hallway, Living room, Office
  • Large bedroom connects with: Bathroom
  • Small bedroom connects with: NULL.

There are 3 data sets used in generation.

  • A tree containing the generated rooms and how they connect
  • An array of objects outlining potential room placement objects and what rooms are currently valid to place there
  • An array of objects that act as a manifest for what rooms are to be placed in this area.

On start of the function, the function loads a manifest of rooms in the area being generated (An array of room types and number of each room to be placed).

The Root node (An enterance room) is added to the tree, the X-Y location of this room is used to add a set of placement nodes around this first X-Y location with the valid room types to connect to the foyer (Office, Hall and Living-room currently, though these room types have no purpose other then place holders for differnt room sizes and descriptions of what objects may later be spawned inside).

While there are items remaining in tihs manifest, a placement node is selected at random and at itsā€™ list of valid rooms is checked against the manifest array, If a match is found, the room object is spawned as a child node to the room that spawned this placement node. (The room tree can be briefly scanned here to find a room with a neighbouring x-y location capable of connecting to this room type to add extra connections for interconnecting rooms).

As the room is placed, The placement node array is scanned for the neighbouring X-Y positions, if a match is found the allowable connecting room types are added to the node, otherwise a new node is added to this list containing only the allowable connecting room for this type.

The process is repeating until the manifest is exhausted, leaving a tree of room objects to be used for mapping the room layout of the game map.

What I am imagining for this in terms of gameplayā€¦
I would like it if only the room currently occupied by the play is rendered, leaving the player to work of auditory clues for where the enemy is.

  • The Enemy AI is to constantly be hunting for the player, randomly moving form location to location
  • The player can not see where they are, but they hear movement each time the enemy moves with volume depending on how many rooms away they currently are.
  • When the Enemy reaches a closed door, they have a chance of attempting to open it and a subsequent chance of succeess. On this event they generate a sound of bashing on the door
  • When the player moves or interacts with an object, they have a chance of drawing the attention of the enemy depending on how many rooms away they are

Gameplay sort of like the old text room-based games where the player will be hunted moving from room to room as they are given written clues about which room the monster is currently in. Replacing the text with a mixture of 2D visuals and sounds.

IE:

  • the player is walking around a room examining objects for information.
  • They hear the sound of footsteps grow larger than fade, a bashing sound can be heard on a far away door.
  • The player decides to risk moving to the next room, they open the door and slip into the connecting hallway.
  • Footsteps grow louder so the player opens the next door and rushes inside. Footsteps grow louder but stop.
  • Player runs over to a cupboard and interacts with it to hide,
  • A loud bashing sound occurs and the door opens, the jinn stepping inside.
  • Player remains motionless not agroing the jinn further until it selects a new location and leaves. (Unless they are unlucky and the AI decides to inspect some of the room objects closer.)

In doing this Map_gen function I have learned a heap about the JS array functions like .some() .find() .forEach(), ect. So that is pretty cool. I am no longer using:

 For(index=0, index<array.length, index++){ if (condition==true){Do stuff; break;}

instead now:

Array.forEach(Dostuff());

or

if(node.find(XYmatch())!=undefined){ Node.attribute = stuff}

Donā€™t worry about your commitment. We have an understanding of sorts. Whatever we can contribute, weā€™ll go with.

Your generation algorithm sounds complicated. I try to write simpler code, maybe thatā€™s why; but, I can see the strength of it (generating connecting rooms, etc.) ā€“ it sounds good. The only real hurdle I see is understanding how to draw a gap between walls/rooms to connect them.

Maybe we can draw every wall as two parts (doorway in the middle), and just fill in unneeded doorways later. Thatā€™s easier.

Letā€™s keep plugging away at this. Please merge my/your changes to master occasionally as things look good. Next, Iā€™ll try to work out how to make only the current room lit.

In my previous code I had rendered each set of terrain tiles as a room which reloaded (Resetting the tile attributes/colours) and shifting location to the otherside of the room when the area transition is reached.

I saw this as a better use of resources, scanning though and changing the colour/attached typeID of each tile instead of purging the whole array and spawning a new set of objects.

Perhaps we can do this again by drawing 1 room as per the attributes of the currently referenced room ID, on reaching an open door and triggering a new area transition, the ID on the room connected to that transition is used to read attibutes from the new room ID.

  • Read room Width,Height and resize existing walls.
  • Remove old doors and place new doors for this rooms links
  • Shift player X or Y location to place them on the opposite side of the room where they will be entering from
  • Scan though the list of furniture for this room object and spawn the needed objects.

We just then need to check the room dimensions and locations of the connecting rooms and do something like spawn some large dark squares of the correct dimension/positions to give the player an indication of what is conncting to the current room

I think they beauty of using a room manifest like this is that in theory you can run the process multiple times to generate multiple room trees which you can then connect together creating 1 large map with discreet locations, IE The player starts in a location with 10 bedrooms, 3 bedrooms, 2 studies and some connecting hallways , as they explore out and reach a new area they might start seeing clusters of offices and rec-rooms as they have moved into a new room-tree that was generated from a different manifest.

This would let us devide the location into several areas/wings instead of having an unstructured random mix of rooms throughout.

Game progression can be built off this like:

  • Player starts in sleeping quarters in an area populated mostly by bedrooms, bathrooms & occasional studies. Door for area transition to next room-tree is locked with the key being spawned in a study the player needs to find.
  • Player finds key and transitions to new area containing recreation + living spaces, progression is blocked by (Item based puzzle)
  • Player reaches new room-tree consisting of offices, hallways and the foyer. The building is locked down by a mechanical lock and the player needs to head to the basement to restart the generator.
  • Ect.

Transitions between room-trees could be the hook where we insert road blocks, reaching a new tree could be the event where we add an extra challenge like adding a new enemy to the mix.