Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MUD programming in C

Status
Not open for further replies.

dakuneko

Programmer
Nov 17, 2000
19
SG
I am interested in creating MUD but I do not know where to start. My problems include: (I would use Unix C)


1. How does the communication between the MUD server and the TELNET client work?

2. What C functions should I use to be able to establish client-server communications in MUD?

I hope someone out there can help about this. Thanks in advance!
 
Zagato,

You don't need to worry about client server issues for a text-only MUD program.

Each user would login to your UNIX machine and immediately run your MUD program.

Communication between different MUD sessions would probably be most easily handled by sidestepping the issue altogether and relying on reading the games data files to find out who's in what room etc.

Even if you want to move to an "Event Driven" game, where something happens to a player and they find out about it whether or not they actually do something, it might be easier to start out by writing a single user game. adding support for multiple users and then adding events.

Sounds interesting actually, private project? Assignment?
Mike
michael.j.lacey@ntlworld.com
 
Thanks Mike!

I think your suggestion is a better approach. I must start out by creating a single-user game then add the multi-player stuff later.

But would it slow down the server if I rely more on the game data files? What I am thinking is to load the game data (the database) into the memory and read from there thereby minimizing file I/O.

I appreciated your suggestion and I will look into this and I'll check to see which one works well.

This is just a private project. Actually, just for fun. I always wanted to create games when I first learned to use a computer.

Thanks!
 
"would it slow down the server if I rely [on] data files?"

Yeah it will a bit -- but not much though.

My approach would be to do the thing in easy stages...

1 single user
2 multi user
3 network comms instead of each user reading a data file

step 3 is way harder than 1 and 2
Mike
michael.j.lacey@ntlworld.com
 
I used the time function and i have the code below (I got it from CircleMUD but i revised a little):
Code:
#define SEC_PER_MUD_MIN		3
#define SEC_PER_MUD_HOUR	(60*SEC_PER_MUD_MIN)	/*     180 */
#define SEC_PER_MUD_DAY		(24*SEC_PER_MUD_HOUR)	/*    4320 */
#define SEC_PER_MUD_MONTH	(32*SEC_PER_MUD_DAY)	/*  138240 */
#define SEC_PER_MUD_YEAR	(20*SEC_PER_MUD_MONTH)	/* 2764800 */

// decade name 
const char *decade_name[] = {
						/*  1 */	"the Rebirth"	,
						/*  2 */	"the Twin Towers"	,
						/*  3 */	"Asheron's Call"	,
						/*  4 */	"the Black Rain"	,
						/*  5 */	"the Blinding"	,
						/*  6 */	"the First Sight"	,
						/*  7 */	"the Moon Rivers"	,
						/*  8 */	"the Sky Fall"	,
						/*  9 */	"the Shields of Fate"	,
						/* 10 */	"the Fates"	,
						/* 11 */	"the Great Battles"	,
						/* 12 */	"the Revolt"	,
						/* 13 */	"the Rebellion"	,
						/* 14 */	"Mica's Regret"	,
						/* 15 */	"the Fierce Winds"	} ;

const char *month_name[] = {
						/*  1 */	"Month of Terebrinth"	,
						/*  2 */	"Month of Czuven Lith"	,
						/*  3 */	"Month of Cian"	,
						/*  4 */	"Month of Diere"	,
						/*  5 */	"Month of Garai"	,
						/*  6 */	"Month of Shevatt"	,
						/*  7 */	"Month of Juno"	,
						/*  8 */	"Month of Micah"	,
						/*  9 */	"Month of Ezra"	,
						/* 10 */	"Month of Durai"	,
						/* 11 */	"Month of Poshu"	,
						/* 12 */	"Month of Quezacotl"	,
						/* 13 */	"Month of Armagged"	,
						/* 14 */	"Month of Osiris"	,
						/* 15 */	"Month of Iris"	,
						/* 16 */	"Month of Ar"	,
						/* 17 */	"Month of MonThaire"	,
						/* 18 */	"Month of Iezapeth"	,
						/* 19 */	"Month of Ttannia"	,
						/* 20 */	"Month of Zerynth"	,
} ;

// day of the week 
const char *day_of_week[] = {
								/* Holy     */	"the Day of Sunnan"		,
								/* Wind     */	"the Day of Celes"		,
								/* Fire     */	"the Day of Helios"		,
								/* Earth    */	"the Day of Zovogath"	,
								/* Water    */	"the Day of Leviath"	,
								/* Thunder  */	"the Day of Innothor"	,
								/* Dark	    */	"the Day of Anak-zuul"	,
								/* Strength */	"the Day of Runaeis"		} ;


// time information container
typedef struct 
{
	unsigned int	year	:	32 ;
	unsigned int	months	:	8 ;		// 20 months in a year
	unsigned int	days	:	8 ;		// 32 days in a month
	unsigned int	hours	:	8;		// 24 hours a day
	unsigned int	minutes :	8;		// 60 minutes an hour
} M_TIME_DATA;



// gets the current MUD time based on the beginning of time
M_TIME_DATA get_current_mud_time(time_t epoch, time_t current_time)
{
	M_TIME_DATA		now ;
	unsigned long	seconds_passed ;

	seconds_passed = (unsigned long) (current_time - epoch) ;
	memset(&now, 0x00, sizeof(M_TIME_DATA)) ;
	now.minutes = (seconds_passed/SEC_PER_MUD_MIN) % 60;	// 0..59
	seconds_passed -= SEC_PER_MUD_MIN * now.minutes;

	now.hours = (seconds_passed/SEC_PER_MUD_HOUR) % 24;		// 0..23
	seconds_passed -= SEC_PER_MUD_HOUR * now.hours;

	now.days = (seconds_passed/SEC_PER_MUD_DAY) % 32 ;		// 0..31
	seconds_passed -= SEC_PER_MUD_DAY * now.days;

	now.months = (seconds_passed/SEC_PER_MUD_MONTH) % 20;	// 0..19
	seconds_passed -= SEC_PER_MUD_MONTH * now.months;

	now.year = (seconds_passed/SEC_PER_MUD_YEAR);			// 0..1553 years

	return now ;
}

// make the time readable to players
void say_time(M_TIME_DATA time_info)
{
	char			am_pm[14] ;
	char			*suf ;
	char			minutes[3] ;
	char			minute_buff[3] ;
	unsigned long	hours ;
	unsigned int	day ;
	unsigned int	decade = 0;

	memset(&am_pm, 0x00, (sizeof(char)*14)) ;
	memset(&minutes, 0x00, (sizeof(char)*3)) ;
	memset(&minute_buff, 0x00, (sizeof(char)*3)) ;

	// determine if AM or PM 
	((time_info.hours < 12) && (time_info.minutes <= 59)) ? strncpy(am_pm, &quot;Ante Meridian&quot;, 14)
		: strncpy(am_pm, &quot;Post Meridian&quot;, 14) ;
	hours = ((time_info.hours % 12) == 0) ? 12 : (time_info.hours % 12) ; // change 0 to 12

	// padd additional '0' to minutes if less than 10
	itoa(time_info.minutes, minute_buff, 10);
	if (time_info.minutes < 10) {
		minutes[0] = '0' ;
		strncat(minutes, minute_buff, 1) ;
	} else {
		strncpy(minutes, minute_buff, 2) ;
	}

	day = time_info.days + 1 ; /* 1..32 */
	// add the suffixes
	if (day == 1)
		suf = &quot;st&quot;;
	else if (day == 2)
		suf = &quot;nd&quot;;
	else if (day == 3)
		suf = &quot;rd&quot;;
	else if (day < 20)
		suf = &quot;th&quot;;
	else if ((day % 10) == 1)
		suf = &quot;st&quot;;
	else if ((day % 10) == 2)
		suf = &quot;nd&quot;;
	else if ((day % 10) == 3)
		suf = &quot;rd&quot;;
	else
		suf = &quot;th&quot;;
	
	printf(&quot;The current time is %d:%s %s.\n&quot;, hours, minutes, am_pm) ;
	printf(&quot;This is %s, %d%s of the %s, the year %d of %s.\n&quot;, 
		day_of_week[(time_info.days%8)], day, suf, month_name[(time_info.months%20)], 
		time_info.year, decade_name[decade]) ;
	
}

int main(void)
{
	unsigned long		beginning_of_time	= 0 ;
	unsigned long		test_time			= 2764800 ;
	M_TIME_DATA	time_info ;

	for(;;) {
		test_time += SEC_PER_MUD_YEAR ;
		time_info = get_current_mud_time(beginning_of_time, test_time);	
		printf(&quot;test_time value:%l [%X]\n&quot;, test_time, test_time) ;
		say_time(time_info) ;
	}
	return 0;
}

There seems to be a problem when I reach the max value an
Code:
unsigned long
can have. It becomes negative. I had an overflow because the value of
Code:
test_time
was greater than the maximum of unsigned long.

It happened this way when my
Code:
test_time
value of 2145484800 was added to 2764800 aka SEC_PER_MUD_YEAR.Because of this the largest year I can have is only at year 777.

Can somebody help me out so that I can go upto the year 9999 without having any overflows?
 
An addition to what was posted above.

If I am to change the data type, what will be it?
 
Correct me if I'm wrong, but isn't an unsigned long guaranteed to be at least 2^32=4294967295?

In any case, if you're having a problem with overflow, see if your compiler supports long long which should be at least 64 bit.

HTH,

Russ
bobbitts@hotmail.com
 
Yes you are correct. It was my mistake back there but just the same an overflow would occur. I am using VC++. I don't think it has long long. Does gcc or cc of Unix have long long type?
 
Hi,

I'm pretty sure the latest version of gcc supports long long (not in front of any *nix boxes right now). djgpp (windows port of gcc) does support it. You should check out djgpp if you haven't already for a high-quality free compiler for windows/dos.


Good luck,

Russ
bobbitts@hotmail.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top