19 Feb, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
Ok,
I've posted a few times about debating whether or not to
start a new code base, so i apologize if i'm asking too similar of a question.
But i've considered C# because it's sort of like C, which i am familiar with.
The benefit i see is that although you dont use pointers (outside of unsafe mode)
with objects you can pass an object my ref, so i dont really see the need.
You get the benefit of high level garbage collection, and you also can use visual studio,
which i personally love. However, there are some things i dont like:
1) Unless you host from a window's machine, little or no mud hosting support (including
the 'Mono Project')
2) Not open source
3) OO in C# is so enforced, i wouldn't be able to code procedurally.
19 Feb, 2009, Davion wrote in the 2nd comment:
Votes: 0
…What's the question?
19 Feb, 2009, David Haley wrote in the 3rd comment:
Votes: 0
C# is not really "like" C other than sharing some syntax. The language really has quite different semantics in many ways.

And yes, hosting options are severely limited.

I'm not sure what kind of code you'd like to write procedurally that you couldn't in C#.

Java might be a better option because more hosts support it, it's already fully multi-platform etc., and also shares similar syntax. In fact, I find that C++ and Java are quite similar in many respects.
19 Feb, 2009, elanthis wrote in the 4th comment:
Votes: 0
Your three facts are wrong.

1) You can get a Linux VPS (and install Mono yourself) for cheaper than any Windows host provider I've ever seen.
2) C#/.NET is fully Open Source thanks to the Mono project.
3) The difference between procedural and OO is all semantics; C# fully supports procedural programming as you can just use static methods, which at the end of the day are just procedural-style functions with enforced namespacing.

DavidHaley said:
C# is not really "like" C other than sharing some syntax. The language really has quite different semantics in many ways.


He did say "sort of like C" which I'm sure meant "looks syntactically enough like C it makes him feel warm and happy." :)

Quote
Java might be a better option because more hosts support it, it's already fully multi-platform etc., and also shares similar syntax. In fact, I find that C++ and Java are quite similar in many respects.


Quite similar… really, you sure about that? They both have syntax taken from C and they both support the same grossly-limiting OO model, but that is the absolute end of the similarities. With that level of inspection, C# is even closer to C++ than Java…

C#/.NET is just as multi-platform as Java thanks to Mono. Platforms supported include Windows, Linux, BSD, Solaris, OS X, iPhone, Wii, and PS3. That's spanning architectures including x86/x86-64, ARM, PPC/PPC64, IA64, Sparc, Alpha, s390/s390x, and MIPS. Not that most of that really matters, since all a MUD developer is going to be interested in is x86/x86-64 support on *nix or maybe Windows. ;)
19 Feb, 2009, David Haley wrote in the 5th comment:
Votes: 0
Yes, in my experience Java is pretty similar to what C++ would look like if you made everything into classes and objects. It adds garbage collection and introspection. I haven't written enough C# code to know if C# is "more similar" than Java to C++, but I do find that Java is quite similar indeed. Perhaps the biggest difference in terms of ease of expression is being able to subclass things on the fly, and, well, having a massive standard library at your disposal.
19 Feb, 2009, elanthis wrote in the 6th comment:
Votes: 0
DavidHaley said:
Yes, in my experience Java is pretty similar to what C++ would look like if you made everything into classes and objects.


The biggest difference really is that Java FORCES you to use objects/classes for everything even where they aren't appropriate, and also forces you to always heap-allocate everything and rely on either the garbage collector or manual method calls to manage resources. There is no RAII in Java. There are no structs. No unions. Generics only appeared in later versions. You can (for no good reason) write C++ code that pretends to be good Java style, but you can't write Java that pretends to be good C++ style. You can't really write C# that pretends to be good C++ style, but you can get closer than you can with Java.

Java was never meant to be C++. The languages used as inspiration for Java were C and Mesa, not C++. The original implementation was attempted as an extension of C++ for practicality reasons (reusing an existing compiler framework instead of starting from scratch), but since C++ and Java's goals are so very very different, the creators decided to drop that work and start from scratch. Java's original target use cases were actually very small applications compared to what C++ is traditionally used for. C# on the other hand was designed to take the ease-of-development strengths of Java, the large-application and systems strength of C++, and merge them together to create a new platform capable of being at the very heart and core of a modern OS. C# could have reasonably been called Java++ if it wasn't for the trademark issues. ;)

(Disclaimer: programming language design and history gets me more hot and bothered than a trio of friendly blonde bisexuals at a nudist beach. That might just be because I prefer brunettes though, who knows.)
19 Feb, 2009, David Haley wrote in the 7th comment:
Votes: 0
Oh, I'm very well aware of the differences, and even the history (although I don't think the history is terribly relevant to the current-day experience). I just don't consider the things you listed to be terribly big differences in terms of how easy it is to express things. The general semantics of the languages are quite similar, in that Java classes are basically like C++ classes with every method being virtual. An example of a big difference would be being able to easily change methods at runtime by swapping field values, or being able to treat functions as first-class values. (No, function pointers don't really cut it.) I've written fairly substantial amounts of code in both languages so I feel I know at least just a little bit what I'm talking about. :wink:

Anyhow, the point is regardless of how many technical differences there may be, I stand by my claim that in my experience, Java feels similar to C++. FWIW it's kind of pointless to argue with feelings :tongue:

(And it's good to see that at least some gentlemen prefer brunettes!)
19 Feb, 2009, JohnnyStarr wrote in the 8th comment:
Votes: 0
Ok, those are all good points.
I understand this is a forum, full of different views, but i think my point
might have been missed.

So, maybe i should make it more clear…

In C, especially Diku based muds use pointers and tons of functions to make the mud.
In C# since everything is an object, its hard for me to see how this might work, EG:

in C, the 'ch' pointer is used to point to the CHAR_DATA struct.
Well thats easy, you could make a class object called 'Character' thats the easy part.
But what do you think about using 'static' methods liberally?
Like, would it be better to have a static object called 'Command' with a bunch of methods?
or would you make Command a reference type and assign them to the characters?

I guess after all this rambling, my precise question is; is it good to take what i know and make a C# version following at least some OO principles? If so, what should be strict objects, and what should be coded proceduraly?
19 Feb, 2009, David Haley wrote in the 9th comment:
Votes: 0
I don't understand your problem with static methods or some static object called "Command". You can model commands as objects if you want to, but yes, you will need some kind of globally shared command object table.

e.g.
cmdObj = CommandTable.lookup(cmdStr)
cmdObj.execute(ch, args)
or whatever.

The best answer I have to your question might not satisfy you. :wink: Use object orientation where it helps you. Avoid it where it makes things more cumbersome. Objects are useful to encapsulate functionality. Objects are not too useful to represent "verbs", but you can get away with that by having classes that only have static methods – in this case, the class becomes like a namespace rather than any kind of object.

Is the distinction you're drawing between OOP and "procedural programming" that the latter has global functions but the former does not?
20 Feb, 2009, JohnnyStarr wrote in the 10th comment:
Votes: 0
That sounds about right.
I know i CAN use C# to do this, but most documentation out there acts like
using global variables, in this case static classes and such is against everything
OO stands for. It is not really my personal views, however, i figure if your going to do
something, do it right. Of course, i CAN just start writing something, but i think that allot of
bad coding starts without a solid objective, thats all i meant.

I want to be sure that i have a the prototype down before i make all the methods.
I am of course aware that i'm sure as time goes on i may have to rewrite some of the code when my understanding of C# grows.
20 Feb, 2009, David Haley wrote in the 11th comment:
Votes: 0
You know, in my Several Years of Programming (doesn't that sound grand) I have started coming to the conclusion that you should do what works best, is easy to understand, is easy to maintain, and is acceptably efficient, rather than follow The Paradigm just for the sake of following the paradigm. The paradigm is a general principle, and like (almost) any rule, there are exceptions. Following it unwaveringly can put you through unnecessary contortions.

It is worth noting that I only allow myself an occasional exception when I am very, very comfortable in the language/paradigm I'm using, and the program itself. While paradigms can have exceptions, making exceptions too easily is just the lazy way out and will lead to inconsistency and therefore probably confusion.

You are correct that not having a clear objective is a recipe for trouble. But consider the situation you find yourself in: you are still learning these languages, and so almost necessarily will make mistakes. How realistic is it to expect to have a very clear objective, when your knowledge of the tool isn't clear to begin with?

At this point I would either start small on something other than a full MUD game, or start on the MUD knowing that you will need (or want) to rewrite some or all of it as time goes on.

Also, there is sometimes value in just starting to write code instead of sitting around in analysis paralysis, even if you will have to revise things later on. Some code is better than no code, after all.
20 Feb, 2009, cbunting wrote in the 12th comment:
Votes: 0
Hello,

I had talked to Ryan Jennings awhile back who had the dlmud codebase, or Devil's Lament MUD. He's working on a C# mud server and a client as well.

You can check it out here if you didn't know about it. You can import rom areas and he offers source code too on the show all downloads link.

http://code.google.com/p/arthea/

Hope this helps,
Chris
20 Feb, 2009, JohnnyStarr wrote in the 13th comment:
Votes: 0
You know, i couldn’t agree more.
I don’t always use 'pc' terminology, but whats frustrating is that I’ve found
C to be such a "literal" language, when you deal with a pointer to a structure, you
are literally talking about the memory address of the structure and you are literally
dealing with the CPU etc. But with C# there are many layers of abstraction so that opens up many different ways of doing one thing. I suppose i could start another project, but the business logic level of a mud is so specific. My brother is an ASP.NET / C# MSAD and after looking at my MUD code he just couldn’t understand "why" anyone would code this. Mind you, asps is not the same as socket programming, but he as very advanced after professionally programming for 20 years, and still he cant suggest where to begin. So perhaps DavidHaley is right, maybe i should just write it and learn at the same time, hopefully i can hack away at those complex abstract layers, such as "inheritance", "delegates", "generics" ETC.
21 Feb, 2009, JohnnyStarr wrote in the 14th comment:
Votes: 0
Ok, one more post and i'll let it die.

One thing i'm curious about is 'speed'.

Yes, machines are amazing in comparison to the "old days" of Diku.
But is it efficient to store all of the: Rooms, Objects, Characters ETC in
virtual memory? I'm guessing i'll get several different responses.
I suppose the answer is "it depends", will i use XML will it be from a SQL db etc.

I see the logic in the day's of C with the power of pointers to dump everything
into structures and quickly "point" to the structures to manipulate / update data.
But most developers these days would argue that accessing and dumping that much data is a waste of resources. I guess the argument makes sense, but i think its more or less contigent on whats better for the system overall, to have multiple trips to the database, or to have to hold all the info in virtual memory.

Any thoughts?

PS, i am thankful for the previous posts, however please consider that disecting every word i have said may not be the most helpful way to make a point. I think its obvious what i'm trying to ask, despite the fact that i may not have used the best terminology. This is a forum after all :)
21 Feb, 2009, David Haley wrote in the 15th comment:
Votes: 0
staryavsky said:
But most developers these days would argue that accessing and dumping that much data is a waste of resources.

Why do you say this?

staryavsky said:
to have multiple trips to the database, or to have to hold all the info in virtual memory.

There is no question at all that hitting the database is slower than hitting something already in memory. The question is whether that increased delay actually matters.

staryavsky said:
however please consider that disecting every word i have said may not be the most helpful way to make a point. I think its obvious what i'm trying to ask

Actually, I am of the opinion that learning a precise vocabulary is the best way for you to learn what this is all about. Furthermore, if you use words that are vague or imprecise, you are less likely to get useful answers, and the whole discussion will be less productive for everybody. To be honest, I often find that it is not at all clear what you are asking. :wink:

Right now for instance, I'm not sure what you're asking. Are you asking what is faster? Are you asking under what circumstances one is better than the other? Are you asking if it matters? For that matter, what are you even asking us to compare?
22 Feb, 2009, quixadhal wrote in the 16th comment:
Votes: 0
staryavsky said:
Ok, one more post and i'll let it die.

One thing i'm curious about is 'speed'.

Yes, machines are amazing in comparison to the "old days" of Diku.
But is it efficient to store all of the: Rooms, Objects, Characters ETC in
virtual memory? I'm guessing i'll get several different responses.
I suppose the answer is "it depends", will i use XML will it be from a SQL db etc.


It really is a question of how much it matters. As a software engineer, you always have to strike a balance between time and space. Time; both the time it takes to develop, and the speed at which the data is processed. Space; the amount of memory used in processing and the amount of external data storage required.

Writing code to do things in "real-time" is a bit different than writing code to do things as quickly as possible. In a MUD, you want events to happen at some selected interval, whether that's on a regular update tick, or by processing events as they come up in a time queue, all you really care about is that you're keeping up with the amount of processing to be done before the next job comes due.

So, if you're on a regular update cycle and let's say you process all pending things in the game every 250ms, you know that you have to get everything done in 250ms or less, otherwise you fall behind and get "lag". If the amount of work you have with a typical load (players, mobs, etc) takes 100ms to do each tick, you have 150ms to let the process sleep (and allow other things sharing the machine to run).

IF you want to spend the time to optimize your code so that it runs in 50ms, that's great… but YOU will gain nothing beyond a sense of satisfaction over having written better code. If you share the CPU with other tasks, they may benefit from it, but your MUD won't see any difference at all. It will simply sleep for 200ms instead of 150ms.

So, with that in mind, the question comes up about space. Your most space-efficient way of developing a system is to make a disk-based one (like LP MUDs, or some in the TinyMUD branch). These kinds of game drivers load things (objects, rooms, mobs, spell code, whatever) into memory as they are first needed and (may) then unload them if nothing touches them for a while. Go ahead and build a 500,000 room grassland – if the players only walk in straight lines going from point A to point B, you'll probably only get 50-100 rooms actually loaded.

The downside of this is, of course, that it takes more time to process events, since they may require disk access to happen before the processing can occur. If your window is 250ms, you might be able to get away with loading an area if you can parse it quickly enough, and it loads in one nice big chunk, but if you're loading an area (for pathfinding perhaps) room-by-room, chances are you'll need several update cycles to finish processing.

THAT brings us around to the idea of how your workload is handled. In a DikuMUD, all processing is done in an update loop, and it has to be completed before moving on. That is, if you're using A* to find a path for a mob to track down a player, that A* algorithm has to run over your whole zone (or world?) before you continue processing other events. So, lots of quick things happen (in memory) fast enough to not matter… but a few expensive ones cause lag because you can't set it aside and continue on the next tick.

In an LP MUD, you have a certain number of execution ticks to do your processing in. When those are used up, your code is unloaded and the next chunk of code is processed. However, you can break your tasks up into chunks if you realize this and have it continue later (the mechanism is a call_out). The good side is that only things depending on the code YOU are using notice the lag. If you're tracking a mob across the world, your mob may lag and seem to not respond as quickly as other mobs…. but other people fighting stupid mobs won't feel any slowdown in their experience.

Ok, with that in mind… we come around to storage. I already mentioned the idea of disk-based vs. memory-based game systems. A memory-based system will be faster unless you're in a memory starved environment… your system shouldn't be using swap under normal operating circumstances… if it is, you don't have enough physical RAM for the workload you're expecting it to handle. Swap isn't there for everyday use, it's there so that a transient need for lots of extra memory can be processed (slowly) instead of aborting.

Reading or writing multiple things at a time is always faster than one-by-one. At least, it should be. Many people over-OOP their systems so container->save() really just loops through all the objects calling save() on each one… which may be much slower since each individual save() might open/write/close files or database transactions. *shrug*

So, if you need time, cache things in memory. Read everything at once (so long as you have the space!), write in batches by setting dirty flags and having an update come along and flush all such things out to disk. If you have plenty of time (or need space!), go ahead and grab stuff directly from disk as needed, and flush it from memory when you don't need it any more. Write immediately, as it will be more robust against failures (crashes, power failures, etc).

If you are writing your code to run on a controlled environment, where YOU control the work load imposed on the machine, then code as you like and as you discover you need more time or space. If you're writing to run on someone else's hardware, you'll have to consider which is more likely to be in abundance, and which is more expensive to obtain more of.

Personally, I think the resource requirements for almost ANY MUD out there are low enough that it really doesn't matter unless you ARE on a restricted host environment. If that's the case, do your homework and see what's the best bang for the buck, and code to take advantage of it.

Hope my rambling helps!
22 Feb, 2009, David Haley wrote in the 17th comment:
Votes: 0
quixadhal said:
IF you want to spend the time to optimize your code so that it runs in 50ms, that's great… but YOU will gain nothing beyond a sense of satisfaction over having written better code. If you share the CPU with other tasks, they may benefit from it, but your MUD won't see any difference at all. It will simply sleep for 200ms instead of 150ms.

Actually, depending on machine load, you are likely to see improvement in case the scheduler decides to kick you out after you've run for longer than your allotted time. You say that other tasks will benefit from your speed improvement: well, it goes both ways. The longer it takes you to finish your task, the more likely it is that you'll get switched out. If you're going to do performance measurements like this, where you determine if you can finish an update in less time than your tick, it is almost useless to do it in total isolation if your actual environment is a heavily shared machine.

quixadhal said:
your system shouldn't be using swap under normal operating circumstances…

It's quite common for shared systems to use swap, as a process that's hanging around and not doing much eventually gets edged out to swap as other processors take up more resources. If you've filled your RAM and still have active processes (or rather, processes wanting to be active), then yes, the machine is overloaded. But using swap per se isn't an indication of overload.
22 Feb, 2009, quixadhal wrote in the 18th comment:
Votes: 0
DavidHaley said:
quixadhal said:
your system shouldn't be using swap under normal operating circumstances…

It's quite common for shared systems to use swap, as a process that's hanging around and not doing much eventually gets edged out to swap as other processors take up more resources. If you've filled your RAM and still have active processes (or rather, processes wanting to be active), then yes, the machine is overloaded. But using swap per se isn't an indication of overload.


That depends how much you trust your OS's swap vs. disk buffering algorithm. Back in the days of the Linux 1.2 kernel, I'd agree. However, using the 2.4 kernel, we found performance improved dramatically when we disabled swap entirely (even with the occasional process dying and having to restart from out of memory errors!). That was a 4GB RAM system where the typical memory load was about 3GB in use… In tuning my desktop for gaming, I've also found the Windows XP kernel is a bit too eager to swap things out to virtual memory in exchange for disk cache.

The thing is, your application can know what data you have is likely to be used sooner rather than later… the OS can't know that and has to treat your real-time Network I/O game server exactly the same way it's treating the SQL database, the bash prompt you left idle 3 weeks ago, and the process that's calculating pi to the 5 zillionth digit.

So, I agree that swap doesn't have to be an indication of a problem… but my servers seldom show more than 2-4M of swap in use (out of 512M of RAM and 1G of swap space)… if I see swap up over 100M, I expect something is unhappy and am usually right. YMMV. :)
22 Feb, 2009, Cratylus wrote in the 19th comment:
Votes: 0
quixadhal said:
Hope my rambling helps!


AAA+++

Would read again.

DavidHaley said:
It's quite common for shared systems to use swap


I think quixadhal may have overstated it a bit, especially for
off the shelf x86-blade/PC-style systems. But increasingly, data center
hardware is outstripping conventional wisdom about swap. I still have
clients ask me what kind of swap they should use, on their 64g (yes g as
in gig) RAM systems. If I'm feeling pedantic I tell them to consult their
app vendor. If they're hip, I tell them to consult their app vendor, then
ask them if they think they really need to swap at all.

Of course, from a practical "will this be my situation" standpoint, I think
most mud ownrs still need to pay attention to swap and assume it'll be
a part of their reality. But from a plan-for-the-near-future perspective,
small ramspace and spinning-disk-swapspace will see great shrinkage.

-Crat
http://lpmuds.net
22 Feb, 2009, David Haley wrote in the 20th comment:
Votes: 0
quixadhal said:
The thing is, your application can know what data you have is likely to be used sooner rather than later… the OS can't know that and has to treat your real-time Network I/O game server exactly the same way it's treating the SQL database, the bash prompt you left idle 3 weeks ago, and the process that's calculating pi to the 5 zillionth digit.

This is exactly why swap isn't necessarily an indication of a problem. If you have a bunch of people on a server running a bunch of programs that they might leave open for ages – especially interactive programs and especially things like IDEs or ipython – you need a lot of RAM to run it all without swap. The total consumption really doesn't matter, it's the space used by processes that are trying to do something that you care about.

We're talking about shared servers here with many concurrent users (i.e., not 2 or 3), not desktops or gaming machines :wink:

Heck, on my desktop, I occasionally hit swap even with 4gb of RAM, if I leave several windows open, have lotsalotsa tabs in Firefox, maybe have a video playing…… or am playing a fullscreen game! I fully expect – and want! – the OS to shunt stuff I'm not using into swap to make room for the stuff I am using.

Cratylus said:
But from a plan-for-the-near-future perspective, small ramspace and spinning-disk-swapspace will see great shrinkage.

For enterprise-level stuff, I would tend to agree – if anything because you can't afford to have your production data center mucking around with swap. But most MUD admins aren't fortunate enough to be in this situation, especially when running on shared hosts with many other MUDs. :wink:
0.0/45