January 2017 Game Dev: 2D PCG ARPG

In general, performance is not a problem until we can see the problem. I wouldn’t worry about reusing existing tiles; that might introduce bugs (eg. state of the doors doesn’t reset).

Instead, I would lean heavily on the side of code that’s more understandable and “straight-forward” like deleting and recreating the objects. The performance hit will be negligible, and if there’s anything I learned from Dajjal’s Minions, it’s that clever code produces clever bugs that require clever fixes… I like easy fixes.

Defining a room as tiles isn’t enough, because we need walls and doors. I’m going to create a “room” object inshaAllah with three walls, and one side having an opening (or door, or locked door). That way, you can just say “give me a room at (x, y) with the opening pointing in direction z” and poof, instant room.

For fog of war, I have some interesting ideas that may produce, well, interesting effects. I’ll prototype it today inshaAllah if/when I get rooms working as an entity.


Signing out. I pushed room generation. The API is pretty readable IMO and easy to use. Excerpt from index.html:

Crafty.e("Room").create(0, 0, houseWidth / 2, houseHeight / 2).seal("nw").door("s").lock("s"); // top-left 

This creates a room that has the top and right sealed (continuous walls) and a door on the left side that’s locked. If I change .door("s") to .door("se"), I get an additional door on the RHS that’s not locked.

Salams,

Room lighting is good to go. Notice there’s a spot in the middle where it gets fully dark.

2 Likes

I think this project is at risk.

@Severok could you please do two things for me?

  • Commit code often. As soon as you have a small change tested and working, commit it.
  • Push code. Even if it’s once a day (more frequent is better).

Right now, our two code branches are diverging, and we’ll have a nasty time trying to reconsolidate. If you can push often, I can at least update mine to merge in your changes.

I also need confirmation on which of these four story stubs you want me to pursue.

That lighting looks amazing. Masha’Allah
Very nice work.

Unfortunately I feel like I am doing nothing but appologising for my lack of contribution lately.
This past week is better left unspoken of, but Alhamdulillah everything seems to be resolved nicely and I am good to go again. On the plus side I learned some new SQL tricks in the process, so I have that going for me.

I am ready to start integrating my map generator into your code as I had done with my Island map generator some time ago.

It is still very rudamentry, I have greatly simplified the generation process I descriped in my previous comment,
I have not yet added the manifest as I had originally planned, but Insha Allah it can be added later if there is time. For now the map is generated is no limit to any specific room type spawning. The only rule is that certain rooms can only be spawned attached to other rooms, that each room can only carry so many connections (As specified by room type) and the generator ceases processing additional nodes for room spawning after it reaches 100.

Here are some visualisations of the generated nodes and how they are linked.
Yellow: House enterance (Goal)
Gray: Hallway
Dark green: Room (Various including Livingroom, kitchen, bedroom, bathroom, study, etc, all definied in subclasses).
Light green: Connection between nodes.

The generator is running reliably, spitting out unique layouts every time.
Unlike my Island generator, this code generates the map almost instantly.

The resulting data is in the form of an array of objects, Each containing an ID code, ID codes for their connecting neighbour in each direction and reference to the room type. In future development I plan to add room furniture spawning to each subclass to populate a list of objects in each room to fill the house with various contents.

I am thinking that when I am parsing the room-objects array, I should check the connecting nodes to see if they are of the same type, then simply not placing a wall between them if they match.
That way hallways are continious in what ever way they run and larger rooms such as Living rooms which may spread across several nodes are drawn as larger and possibly non-rectangular rooms.

Edit: I can’t push my branch, need permission granted for this repo.
Ashes halp?

1 Like

There’s nothing to apologise for. Life happens (it happens to me too). For Deen Games, I always look for collaborators who are self-motivated to work, no matter what happens to them. Because we all have busy lives (school, work, friends, wife/kids, hobbies, gaming, etc.)

I don’t know if it’s just the colour scheme you chose, but it makes me think of a jungle, thick with vines and foliage, our hero unable to see his way forward …

The wall thing might not be as hard as you think. Currently, a room is just “four walls-with-doorways in a certain area.” You can probably grab a wall and destroy it.

Your previous generation had for-loops within for-loops within for-loops, which means LOTS of crunching/computation. That’s why it took a long time.

I’m curious to see if it lags when the player moves. The lighting check is very naive; when a player moves, it loops through all the rooms and stops when it finds the first room to light. In runtime complexity, it’s O(n) and n/2 iterations on average.

(That’s something we learned in comp-sci. O(n) means it looks through everything – n items – some number of times, eg. it does n operations, n/2 operations, 5n operations, …)

Looks great, I hope you can push it to the repo soon so I can pull/merge and get a look for myself.

Yep, that is why I went with a linked-list rather than a large 2D array like last time.

Looking at how the code integrates, it might be an idea for me to alter the room object.
Currently it has 4 attributes that define who it is connected to to the north, south, east and west respectively.
room.N .S .E .W the code would look cleaner if that were instead an array I could step though while deciding where to place the walls/doors.

I pulled your branch and merged before creating a new branch for myself.
Ultimately using your code in its’ current state as my starting point.
I have since added 2 new files. One containing the higher-level map-gen code and the other defining my room objects, specific room object subclasses and related functions for placing and connecting them.

Currently I am adding code to call my higher level code from your main code in index.html and parse the resulting file using your room objects. Currently running my branch will just give a white screen, but Insha Allah I will have that resolved before the end of tomorrow.

I have started writing the code in the main start function to step though my generated room-list to spawn your room objects in their designated locations. The X,Y attributes relating to their spacial location and the link IDs determining if a Wall, Door or open space should be used on each side.

Originally I had intended to have various room sizes, but decided it would be simplier if I had every room a constant size and just allowed certain rooms to extend their sizes by spawning child nodes of the same type in neighbouring locations. Due to this it now spawns large hallways that can wrap around corners and open into wide halls. Living rooms that don’t have to be a static rectangle shape, etc.

That visualisation code has all been removed in merging everything into your code.
Though for the life of me I can not find where you defined the room dimensions.

I am trying to commit the code as is in my branch so you can have a look at what I have done and slap me across the head as needed.

Though:
remote: Permission to MuslimGamer/house-of-jinn.git denied to severokST.
fatal: unable to access ‘https://github.com/MuslimGamer/house-of-jinn.git/’: The requested URL returned error: 403

Sorry, I didn’t realize it added the MG team as “read only” access. I switched it to Admin a second ago and you should have access to push/branch/etc. now.

I didn’t define the room dimensions anywhere. create takes in the x, y, width, and height of a room. That’s why the first call in my branch is Crafty.e("Room").create(0,0, houseWidth / 2, houseHeight / 2) – it creates a room at (0, 0) that’s 512x288. I look forward to being able to pull your code.

Meanwhile, I’ll work on creating a randomly-wandering jinn that kills you on contact. I’m almost tempted to use the Big Boo sprite for him :slight_smile:

My branch has been pushed as is.


Originally I had plans for 4 jinn based loosely on some of my favorite SCP and some horror games.
I am a huge fan of surreal horror, be it Lovecraft, Poe, various SCP or various other sources.

If you haven’t played it yet I would very highly recommend downloading and playing “SCP Containment breach” which is amongst my all time favorite free indi-games and a major source of inspiration for various ideas.

The main Jinn who pursues you from the start of the game, just being a generic AI, Idea loosely based off the Scissor man from the Clock-tower game from the SNES era that originally inspired me for this specific project

This being a character that would hunt the player while they search around the enviroment looking for items to collect to solve item-based puzzels and places to hide. In the event the Jinn lured into a room with the player, depending on how agro’d they are, they will either leave if the player is hidden or search the room, possibly giving up after checking an object or 2 to find the player depending on how certain they are of the players position.

I was thinking of the game being dark with the player having a flashlight that would light up the room in a cone in the direction the player is facing, with the option of hitting a lightswitch on the wall to light the whole room.


As the player opens up new areas, I was thinking of adding additional Jinn with differnt AI such as:

Dark hunter -
Based loosely on SCP-173 which later inspired the ‘Weeping angels’ from Dr Who.

http://www.scp-wiki.net/scp-173

https://creepypastapeeps.files.wordpress.com/2013/12/scp___173_by_nexnirvos-d6jisbo.jpg?w=350&h=237

In Game:
Highly agressive, significantly faster than player.
Completly freezes in light or when viewed by the player.
During an encounter, the player must either activate a light or keep the mouse cursor over this jinn as they move to keep it still. Shifting the cursor away to interact with a door or lightswich will allow the jinn to rush towards they player if they are not quick enough.

Light-Hunter - Shy
Based loosely of SCP-096 “The Shy Guy”. Likely source of inspiration for the Minecraft Enderman being agro’d on player focus (Along with Slenderman)
http://www.scp-wiki.net/scp-096
https://s-media-cache-ak0.pinimg.com/736x/f2/3d/45/f23d4534a7dd1ee0db88118d46f9551c.jpg

In game:
The Opposite of the Dark-Hunter. This Jinn is completely passive unless exposed to light. If the player enters a room with this Jinn and turns on the light or looks at it (Shining the players torch) for longer than 2 seconds the Jinn becomes highly aggressive and fast as the dark hunter. The difference being that once agro’d, removing the light will not calm this Jinn and the player has only a slim hope of running.

Wall-Hunter
Loosely based on SCP-106, "The old man"
Can move though solid materials, occupies a pocket dimension using any flat wall as a doorway to enter our world. Captures its’ prey dragging them into its’ pocket dimension to hunt and consume.

http://www.scp-wiki.net/scp-106
https://i.ytimg.com/vi/cxvCQwX4v94/hqdefault.jpg

In game:
Highly aggressive, but slow moving. Does not wander the map, but instead will emerge out of a random wall in the players room if they remain in the same location for too long.


In terms of story, I was thinking that if we go the route with various jinns being added as the player progresses, we could maybe set the game in a former orphanage.

  • Quran has lots of references to the treatment of orphans, so we have our Islamic hook along with Jinn
  • Children had been treated unfairly by the administrators of this facility, their unhappiness had attracted the Jinn who gained strength here
  • Orphanage is now abandoned (Maybe repurposed and sold to the protagonist?)
  • Jinn carry an imprint of the personailities of various children who lived there, Progressing though the building the player finds journal entries and case reports of 4 key children who are prototypes of the Jinn encountered.

Thanks for pushing your branch. I’ve pushed to my branch with the generic jinn moving around.

Download SCP Containment Breach now.

Reading your post at 11:30 at night with the lights of was NOT a good idea and gave me a major case of the creeps.

Bad treatment treatment of children won’t attract jinns, but maybe someone using magic might. In the orphanage. Also, the major issue I see is that jinns don’t kill people (normally) – only in cases of possession where someone tries to do ruqya and is threatened that the jinn will kill the possessed person.

Maybe the four jinns are really four possessed children.

I need to play something with sunshine and rainbows right now.

1 Like

Hey @severok if I may propose, some changes to your code please please please please?

  1. Please use more white-space, especially when you have arithmetic operators, brackets, etc. It really helps with readability.
  2. Both of us defined a “room” class. This, could be a problem.
  3. The “prototype” folder is for generally-reusable prototype code I’ve used across multiple games. I think `mapbelongs somewhere else; do you agree? Could you move it?
  4. Your code doesn’t compile (I get a JS error). And it makes my head hurt. I can’t understand this:
if(map.locations[map.locations[roomdraw].N].Type!=map.locations[roomdraw].Type]){newroom.door("n");}

I understand now that map has an array of locations, and that roomdraw is an integer referring to the current room in the iteration. But I can’t understand what map.locations[map.locations[roomdraw].N].Type could mean.

This is a great case where you can use variables to add tons of readability, and you can tweak your variable names to promote understanding. I would change roomdraw to currentRoomIndex and map.locations[currentRoomIndex] to currentRoom. That would help.

I can’t decipher how to make this compile, so I’ll wait it out, and see if I can add a journal-page entity next.

2,3,4 - Done
1 - Will try to keep in mind.

Do you not like indexes within indexes? :grinning:
how do you feel about parsing buffers with pointer arithmatic?

Each room ID, corresponds to its’ index for the array that holds all the room data.
Each object within that array has the attributes N, S, E and W for North, south, east and west respectively. These hold the IDs for the rooms connecting in that direction. the value within the index map.locations[roomdraw].N returns the index of the connecting room which subsequently passes as map.locations[index].Type, returning a string indicating what kind of room it is (Hallway, Living room, bedroom, ect).

Basically it says that if this room is a different type to the one north of it, place a door.
It is being handled in a better way now, where I check these type comparisons while placing the rooms and simply write a string for each room indicating where the door, wall and open-air placements should be.

On drawing the room using your function in the main code, I just check if that string is populated by nsew characters and call the relevent object functions if needed.

Room types also dictate what rooms can be spawned from them (EG you can have a bathroom spawning attached to a hallway or bedoom, but not a kitchen). For now this helps generate rooms in a branching tree fashion, but ultimately it should help when these various room types start getting populated by approriate furnishings.

I have made some more progress integrating my mapgen code with the current code.
This is still in my branch and does not yet have the jinn code added. That will need to come next




Although still far from perfect.
The game does not seem to spawn the player or apply lighting effects when the house contains 100+ rooms.
I currently have the generator set to generate upto about 70 rooms.

The Crafty viewport functions also seem to not be working.
I had to disable them to get those images above, with these functions present I just get the green background from the Crafty windown with no rooms, player or lighting effects.

You might notice in the last image, there is no wall between the current player room and the room to the north. This is due to the rooms being of the same type causing them to be drawn as 1 larger room.
If possible I would like to have the lighting effect extend to these connected cells, otherwise will need to work out how to define larger roomsizes in the generator along with the additional locations for doorways.

At this point unfortunately however, I will have to put my work on hold as tomorrow is the last night before I head overseas and we have to leave at 3am to head to the airport.
If you want to put this all on hold until I return then I would be happy to pick this up again from this point later, otherwise you can take what I have so far and run with it.

Edit:
I have disabled the Crafty viewport functions in the main code and instead added a viewport ‘CentreOn’ command on the player movement code. The results are perhaps a little slow, but it looks cool.

Though currently the lighting effect is limited to the starting location.

Taking a quick walk around the generated structure, I am quite pleased with how it has turned out so far

There are some nice winding corridors, little branching paths I am guessing are bedrooms + ensuites, interconnecting rooms, paths that branch off, to connect together again later…

Final edit;
Okay, it is 2am and I got as much working as I can for now, I go to push my work and git starts complaing about my branch having a broken ref…

warning: ignoring broken ref refs/remotes/origin/severok

Not sure how to resolve it, and honestly this time of night it would be stupid to attempt anything.
I have uploaded my current code to my previous repo https://github/severokst/JSTest.
You can check it out there for now, and Insha Allah I can get what ever issue has occured now, resolved

1 Like

If you can use console.log instead of alert, and the JS console window, that would really help you a lot. Seeing nothing but green may be a JS error showing up that you didn’t see.

Please check this log of your branch on the original repo: does it look like it has all your changes?

If yes, your changes are good, and you can ignore the broken ref. I will keep posting inshaAllah and running with this as much as I am able in your absence.

InshaAllah have a safe trip and try not to think about jinns until you get back. :smiley:

1 Like

All these jins lol

Guys put in some levelup mechanics! Speed could be a stat! Discovering more rooms = XP!

@Wulf feel free to open a PR :slight_smile:

@Severok please try to impart your vision of what this game is before you go as best as you can … I fear I may take it into a totally different direction (and we won’t have time to “go back” and undo it / redo it in your image).

I’ll keep things to my branch as much as possible, although trying to undo/redo is probably a mistake. We’ll see. We can always just modify it for next month’s game.

Have you tried playing SCP containment breach?

What I am imagining is much like that + clock tower in a topdown 2D adventure.

I guess my overall wishlist is like…

The player is alone in a giant house. Has to escape. Enemies Pathfind around the house searching for the player like 1 giant game of hide and seek. Enemies wander from room to room at random unless they hear player actions, may become agro to player or simply attracted to player room depending on how much the player is doing and distance.

Player may hide by interacting with room objects like bed or cupboard if they hear an enemy approach. Being seen by enemy is highly dangerous. Player has no ability to fight and little chance to run. Game over on contact.

Remember in my MVP prototype, if the player is spotted they had very little chance of escape? That is the aspect I found most fun there. That the player needed to plot a path to the goal avoiding the attention of the enemy and using the terrain to player advantage. Player should feel hopeless in same room as enemy, having little power in the open.

The enemies path find around the house searching for player. Randomly selecting rooms to move between. preference for open doors and hallways over closed doors, but chance of bashing doors open.

During gameplay player can only see contents of their own room. Only clue for enemy position is sounds of movement and door bashing, the volume for which depends on how far they are.
Enemy is restricted by walls and doors, can not pass through walls.

Potential story integration though various journal objects discoverable in level. Potential for item based puzzles or simple key hunts to progress through areas. Potential to add new enemies and AI types on reaching each new area.

1 Like

As-salaamu 'alikum,

I have too much to say. I deleted this post because it was plain wrong.

Can we please:

  • Use consistent naming conventions. Variables should be likeThis, not likethis or likethis.
  • Use Crafty consistently. map shouldn’t be a JSON object. room-gen doesn’t represent an entity.
  • Avoid code duplication like the plague. It IS the plague, and copy-paste bugs still hurt. I see a lot of your room gen could be boiled down to data.
  • Stop putting numbers like 50 and 4 in the code. They always mean something. What do they mean? Please create a constant with that name, like POSSIBLE_DIRECTIONS and reference it that way.

By the way, the SNES game you like is Clock Tower. I read the Wikipedia article and got some good ideas for gameplay. I also started an excellent course called “Agile for One” and have some ideas on how to prioritize and prototype effectively. More on that once I modify your code to be more consistent and readable.

I’ll try to update less often (weekly) to avoid giving you a wall of text when you come back. Like this one.

Ashes, when you’re done with the course, it would be really cool if you gave us a brief summary of what it taught you! InshAllah it will be beneficial journey.

1 Like

I hope you read my previous post, because I edited it heavily.

I need to put on my PM hat more. Much more.

Summary of work we did this past week:

  • Procedurally generate an awesome mansion
  • Proper light/dark rooms
  • Fog of war (you can partly see rooms after you’ve seen them once)

Demo:

The theme of this week is: jinns.

1 Like

The theme of this week was: jinns. While the week isn’t over, here are the jinns. This is with darkness temporarily nerfed. (NB: sorry for the large files.)

I tried to keep the theme of “once they find you, you’re dead.” With the exception of Bubbler: I wanted to invoke feelings of:

  • ZOMG he’s right around the corner RUN AWAY
  • ZOMG he’ll be here in a second RUN AWAY

Without further ado:

  1. Wanderer: wanders from room to room, randomly through all walls. Chases you on sight. Basic jinn.

  1. Walker: walks to adjacent rooms or open rooms. Chases you on sight. Also basic jinn.

  1. Shy Guy: doesn’t move until you see him. Then he doesn’t stop chasing you.

  1. Jumper: pocket-dimension jinn. Once he chases you, he’s always there. You can’t get away.

  1. Splitter jinn: basic walker jinn. But when he sees you, he starts multiplying uncontrollably.

  1. Stalker jinn: a walker. He can sense you wherever you are, and always walks closer toward you.

  1. Bubbler jinn: like the wanderer. He exhumes “bubbles.” If you touch one, he immediately goes aggro.

My favourites are the jumper, bubbler, and splitter.

1 Like