Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > The real world > Idle chatter

Reply
 
Thread Tools Display Modes
Old January 25, 2009, 15:24   #1
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Lightbulb Developing a RL

Ok, I suppose technically it would fit better on r.g.a.*, but I don't feel comfortable with such a large audience yet.

All the threads here about variant development have me inspired to start work on my own roguelike!
Nothing too detailed is fixed yet, as I want the basic engine up and running before really presenting anything.


I'm roughly following the 15 steps from the roguebasin wiki, as a guide for milestones. So far I got a scrolling map, the base classes for actors, items, terrain and effects (already used for testing purposes).

Time is implemented through firing heartbeat events in the main loop, received by all objects on the map. Actions cost energy and receiving a heartbeat restores energy or calls the action routines. The only difference so far between PC and NPCs is that if a PC has its 'currently active' flag set, the heartbeat stops until the PC is no longer active (energy below the action threshold) - effectively waiting for keyboard input.

The message system is event-driven as well, which is especially nice for debugging, as I can just listen to all messages directly in the game window.

Display is traditional ASCII (tiles shouldn't be a problem, as the representation is the responsibility of the object, the display class just draws what it is told), although I had to implement my own double-buffering to avoid flicker.

Not too bad for a couple of evenings, although I expect that progress will get slower once I get to data files, inventory management and effects. Not to mention map generation beyond the current completely random fill. Truth be told, I dread map generation. I'm tending towards a tree based approach - dividing the map into parts, dividing the parts again... then placing a room in each part and traversing the tree, connecting the parts. So far, that is the only approach that I could wrap my head around when it comes to thinking about the actual implementation.


But next up is the menu system - I'm still not decided if I should display it in a separate area or in the message panel. Right now, I just want the basic 'Really quit? y/n' message to work. Any further menus should then be a matter of inheritance and responding to inputs.

Wish me luck.
pndrev is offline   Reply With Quote
Old January 25, 2009, 15:34   #2
Elsairon
Adept
 
Join Date: Apr 2007
Posts: 117
Elsairon is on a distinguished road
In my experience, r.g.r.d will welcome you with open arms, generally after you have some semi-working something released. I'm currently in the item/effect stage myself, in the middle of a long few month hiatus from coding.

Best Wishes and Luck (aka perseverance)
Elsairon is offline   Reply With Quote
Old January 29, 2009, 00:13   #3
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Got menus displaying and properly catching input. I also found the reason for the map scrolling not working 100% as expected, but it was more the fault of 'just put a hack in so at least something gets drawn'.

Next up is correcting that mistake by implementing movement routines where they belong, the map / actor objects instead of the game loop. That will probably optimise the drawing and refreshing routines of the display as well, eliminating that last annoying flicker that just occasionally happens.

FWIW, up to now, I had the display store an array of Glyph (which store a character and it's colour). To determine which elements need drawing, it went through the objects in the map and recorded a second 'delta' array. That was the one being drawn, then the full map gets updated from the delta (only really needed for fast, full refresh).

That works, but if I put the 'move' routines with the actors (and items, effects), I can fire a simple 'has moved' event that causes the delta to be written for exactly that object, instead of polling all available objects for new positions whenever the player presses a key.

Side-effect: Depending on the actual implementation (exactly when to fire that event and if updating the delta automatically draws it as well), I might get animation for free. And since I only have to update two tiles (the old position and the new one), it should be reasonably fast as well.


So, next up is:
- Implement real movement and event-based screen updates.
- Start working on an explorable map as opposed to everything being visible.

After that, I'll see. Probably basic items and inventory. And working out a couple of magic numbers found purely by guesswork and approximation that are currently used in the screen drawing routine.
pndrev is offline   Reply With Quote
Old January 29, 2009, 21:30   #4
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Fixed the remaining flicker of the screen, because a) it was annoying as hell when debugging and b) if I couldn't even get a simple '@' running around without intermittent flickering, I might as well give up and stick to the apps I'm coding at work.

Of course, this also meant implementing the events for screen updates from actors instead of a general 'lets see if we can spot the difference'. (which, btw. wasn't the cause of the flicker...). Which fortunately was one of the rather high-prio tasks in my todo list.

I'll sideline the explorable map for a while longer - theoretically it would use the same event system to toggle 'explored' and 'seen' flags on the terrain. But knowing myself, once I start, I'll head down the lane towards LOS, and THAT I'm not ready to tackle yet. Working on structuring the player-input handling routines so they can bump into things, that seems currently much more tempting.

Although... A basic floodfill with a range-from-origin limit might work as a first approximation? I guess that's how lanterns or light are done, anyway. Might also come in handy when checking for connectedness of rooms etc.


OT: I hope it's okay that I abuse this thread as some sort of running commentary? I could move it to a website or blog, it's just that I sometimes start seeing solutions once I type out my thoughts about the problem. And of course, I count on someone yelling 'stop!' when I'm about to do something extraordinarily stupid.
Other than trying to write a RL while already developing software as a dayjob.
pndrev is offline   Reply With Quote
Old February 8, 2009, 15:31   #5
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Finally got around to continue working on this.

Implemented a basic inventory - picking up, dropping and using items. In the course of that I refined the menu system (for updating menu text while the menu is displayed) and tweaked the basic message system (so everything gets send through the same channels instead of having a few special cases).

A very pleasant surprise was how much of picking up and dropping already was supported in my map code. I just needed to plug in a new list for items, and everything from there went automatically. Three cheers for OOD!


I also decided on a theme for the game. So I'm currently having two different brainstorming lists - one with everything that somehow might fit the theme and one with what I think might get implemented in this first version. When I get the next step done, basic stats, I'll take a break and talk about the theme and scope. From what I have so far it will definitely be a coffee-break RL, but I try to design everything with a possible expansion in mind.

For stats, so far I'm toying with the idea of borrowing Fallouts SPECIAL system. Which would fit in nicely with the theme idea.
pndrev is offline   Reply With Quote
Old July 17, 2009, 15:44   #6
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Good god. I knew I would have a shortage of time and motivation, but seriously...

Anyway, I started tackling the map generation, not because it is the most pressing issue, but because I was interested in finding a simple, easy algorithm. That's probably the best way to keep making progress - find interesting things to do.

So here is the basic skeleton of the code. I'd appreciate some input if it really might work. A few 'magic' bits are in the comments, but what concerns me is the recursion for the division of rooms into smaller ones.

A Map class that starts it all
Code:
public class Map
{
	private ArrayList _world;
	public ArrayList World
	{
		get { return _world; }
	}
	
	public Map()
	{
		Room main = new Room(0, generateDepth, 0, 0, screenWidth, screenHeight);
		_world = main.Build();
	}
}
The Room class with the recursive algorithm.
Code:
public class Room
{
	// some collections to store information
	private ArrayList _rooms;
	private ArrayList _corridors;
	private ArrayList _floor;
	
	public Room(int iteration, int maxiteration, int x, int y, int w, int h)
	{
		_rooms = new ArrayList();
		_corridors = new ArrayList();
		
		// only generate to a certain depth
		if (iteration < maxiteration)
		{
			// recurse into more rooms
			Divide(iteration, maxiteration);
			// generate main corridor between subrooms
			Connect(_rooms);
			// connect main corridor to subrooms proper
			foreach(Room r in _rooms)
			{
				r.ConnectWorld(_corridors[0]);
			}
		}
		else
		{
			// flood fill _floor from x, y, width, height
			_floor = BuildRoom(x, y, w, h);
		}
	}
	
	private ArrayList BuildRoom(int x, int y, int w, int h)
	{
		// ...magic happens...
		return room;
	}
	
	public ArrayList Build()
	{
		if (_rooms.Count == 0)
		{
			// end of recursion, no subrooms and corridors exist
			return _floor;
		}
		else
		{		
			// recurse through subrooms
			ArrayList subfloors = new ArrayList();
			foreach(Room r in _rooms)
			{
				subfloors.AddRange(r.Build());
			}
			
			// add corridors
			foreach(Corridor c in _corridors)
			{
				subfloors.AddRange(c.Floor);
			}
			
			return subfloors;
		}
	}
	
	private void Divide(int iteration, int maxiteration)
	{
		iteration++;
		
		// randomly choose new x, y, width, height (fitting within current room, not overlapping)
		Room sub1 = new Room(iteration, maxiteration, x1, y1, w1, h1);
		Room sub2 = new Room(iteration, maxiteration, x2, y2, w2, h2);

		// store subrooms
		_rooms.Add(sub1);
		_rooms.Add(sub2);
	}
	
	private void Connect(ArrayList roomlist)
	{
		// connect each rooom to the next one, without looping back
		foreach (Room r in roomlist)
		{
			if (roomlist.IndexOf(r) < (roomlist.Count - 1))
			{
				Connect(r, roomlist[roomlist.IndexOf(r) + 1]);
			}
		}
	}
	
	private void Connect(Room r1, Room r2)
	{
		// connect subrooms
		Corridor cor = new Corridor(r1, r2);
		_corridors.Add(cor);
	}
	
	public void ConnectWorld(Corridor corx)
	{
		// connect incoming corridor from parent room to each subroom
		foreach(Room r in _rooms)
		{
			Corridor cor = new Corridor(corx, r);
			_corridors.Add(cor);
		}
	}
}
The Corridor for connection rooms, with some magic bits for finding the path.
Code:
public class Corridor
{
	private ArrayList _floor;

	// complex constructors omitted, basically all should lead to the same result
	// connect two rooms using the shortest direct path
	public Corridor(Room r1, Room r2)
	// connect a room to a corridor using the shortest direct path
	public Corridor(Corridor c1, Room r1)
	// connect two coordinate using the shortest direct path
	public Corridor(int x1, int y1, int x2, int y2)
	{
		// find most direct way between the starting points and fill _floor
		_floor = FindPath(x1, y1, x2, y2);
	}
	
	public ArrayList Floor
	{
		get { return _floor; }
	}
	
	private ArrayList FindPath(int x1, int y1, int x2, int y2)
	{
		// ...magic happens...
		return path;
	}
}
Working through the code on paper seems like it actually results in a useable map. But if anybody has experience with a similar "divide rooms into smaller ones and connect" generation, I'd really appreciate comments.
pndrev is offline   Reply With Quote
Old July 17, 2009, 18:01   #7
Nolendil
Adept
 
Nolendil's Avatar
 
Join Date: May 2007
Location: Paris, France
Posts: 171
Donated: 10 euro
Nolendil is on a distinguished road
I haven't read your code but your description ( "divide rooms into smaller ones and connect" ) makes me think about that method :
http://roguebasin.roguelikedevelopme...eon_generation

I'm thinking about coding a RL with a friend but we're not satisfied with any algorithm so far. We're still searching.
__________________
A(3.2.0) C "Angdiira II" DP L:36 DL:44(2200') A+ R+ Sp w:Whip of Westernesse(+10,+10)(+2)
A Mx H- D c-- f- PV+ s- d P++ M+
C- S-- I So B++ ac GHB- SQ+ RQ++ V+
Nolendil is offline   Reply With Quote
Old July 17, 2009, 21:20   #8
pndrev
Scout
 
Join Date: Sep 2008
Location: Fürth, Germany
Age: 40
Posts: 38
pndrev is on a distinguished road
Yep, that was basically the idea. It's the simplest algorithm I can think of, short of randomly placing stuff.
pndrev is offline   Reply With Quote
Old July 18, 2009, 08:21   #9
Nolendil
Adept
 
Nolendil's Avatar
 
Join Date: May 2007
Location: Paris, France
Posts: 171
Donated: 10 euro
Nolendil is on a distinguished road
The problem I have with this algorithm is that I feel the variety of dungeons produced is not wide enough for my taste.
However, it seems perfectly functional and produces levels where all rooms are guaranteed to be connected.
You can start with that anyway, it's not hard to code and you can change it later if you're not satisfied.
__________________
A(3.2.0) C "Angdiira II" DP L:36 DL:44(2200') A+ R+ Sp w:Whip of Westernesse(+10,+10)(+2)
A Mx H- D c-- f- PV+ s- d P++ M+
C- S-- I So B++ ac GHB- SQ+ RQ++ V+
Nolendil is offline   Reply With Quote
Old July 18, 2009, 10:06   #10
Sirridan
Knight
 
Sirridan's Avatar
 
Join Date: May 2009
Posts: 560
Sirridan is on a distinguished road
Quote:
Originally Posted by Nolendil View Post
The problem I have with this algorithm is that I feel the variety of dungeons produced is not wide enough for my taste.
However, it seems perfectly functional and produces levels where all rooms are guaranteed to be connected.
You can start with that anyway, it's not hard to code and you can change it later if you're not satisfied.
That's the one I'm going to use myself. Right now the dungeon I use is pre-generated. Once I have item code, and monster code and combat done, then I can move on to dungeons.

I'll probably beg people to test mine... and I'll gladly test anyone elses!
Sirridan is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:09.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.