Sean Middleditch » Advogato
ncm:
I have a SyncMaster 206BW and my roommate has the 226BW. Both of our monitors look gorgeous with the default X and GNOME settings on Ubuntu. I can’t imagine that the 205BW is that different. I’m using DVI (NVIDIA 6600) and my roommate is using VGA (Intel GMA 3000).
Looking at my old monitor, a 172T SyncMaster LCD, the screen was always beautiful, on both VGA and DVI using either NVIDIA cards or SIS integrated chipsets. I recently moved it from my home to my office, running some ancient Matrox Millenium II card over VGA, and sure enough, it looks like shit.
Moral of the story? It might not be the monitor that’s at fault if things look like crap.
I’ve posted all my old Advogato diary entries to my blog here. They’re all a little funky given how Advogato didn’t support entry titles and the like, but at least they’re all here. They’ll all under the Advogato category, strangely enough. ;-)
Blog
skvidal: Try WordPress. I’ve installed it today (here), and am so far very pleased.
I do need to get my old Advogato entries posted into it, however, and also find a way to have entries posted in WordPress get posted to Advogato as well.
The Advogato XML-RPC API will make both easily possible, I’m sure.
Nafaii77: first off, there are indeed C++ compatible garbage collectors. I use the Boehm GC (http://www.hpl.hp.com/personal/Hans_Boehm/gc/) and it works perfectly.
So far as whether you should or should not use delete… when you have allocated memory, you need to free it. It is possible to use systems that call delete *for* you, however, such as a GC, using reference counted objects, special language constructs like graydon’s idea, and so on. In the end, something is of course freeing the memory; it’s just possible for it to be code you don’t touch/write yourself.
async: Whether it’s a NULL pointer or a None/NULL object, either way it’ll result in some kind of error on usage vs a warning at compilation. A None object can have the benefit that any message sent to it can result in an exception (vs a crash; although a segmentation fault can be caught and turned into an exception as well.), but that doesn’t really solve any problems. If you’re actually writing code to catch exceptions caused by misusing nil/null/none objects, you’re doing something wrong.
As to the cycles, my point was that the language cannot possibly enforce a lack of cycles. There is no way to detect when one is being created without doing expensive cycle checks during ownership transfer (again back to generating and catching signals at runtime). The only option available would be to make it impossible to transfer ownership of pointers, but doing so would make quite a few things incredibly difficult and/or impossible. For example, if codepath A allocates an object on behalf of codepath B, and then B wants to put the newly allocated object into some kind of list or whatever to retain management of the object, a way to transfer ownership is mandatory. Which means there’s always a way to create a cycle.
I got a mail regarding this issue as well, though gradydon said he’d post it to Advogato, so I’ll reply to that publically when he has.
Unique IDs
AweMUD used to have a concept of unique IDs attached to every entity in the system. The purpose was mainly to allow scripts and such to lookup specific entities across shutdowns/reboots (serialization).
These caused several problems, however. For one, there is no quick, efficient, guaranteed way to get a unique ID. Second, users who copies around entities definitions in files would almost always forget to delete the unique IDs, resulting in problems.
I have since removed these unique IDs. I am getting to the point where they could be very useful, however. The current plan is to provide a non-unique set of IDs, or tags, for every entity. In cases where very specific entities are needed (admittedly rarer than I had originally predicted) scripters/builders can attach their own custom tags. In other cases, the tags could be a great use in searching for collections of objects. (Perhaps all objects that have been in a certain room get a particular tag attached, and some script later can use that to find all those objects. This could provide for some interesting world features.)
I’m working on building up a simple hash C++ class for this. Each object would get added to the hash table baed on its tags. Tag lookups will, of course, compute the tag hash, find the resulting bucket, search that bucket for the specific tag, and then return the list of objects in that bucket. Then I can write up some demos to show what can be done with tags.
Access Control
The old accounting code in SupportWeb (internal work application, which I would releae to the public if I thought it was worth the release hassle) had very, very buggy access control code. I’m still ashamed that I wrote it, but then, it is the kind of code that happens when you have a simple clean design to begin with, and people keep adding more and more needs on top of things down the road.
In any event, the new code is a lot more solid. Each purchase request field is now has its own access flag, and all access checking takes place in a single function that calculates the available access flags for each request based on the request field values/state and the current user. Much nicer.
Of Pointers and Men
graydon: “in other words, the rules of the language should make cyclical ownership, null pointers, and double-ownership inexpressible.“
How exactly do you make cyclical ownership inexpressible? How is that possible? If you have two distinct objects, each make have an owning pointer, yes? And you can transfer ownership between pointers, yes? So what stops you from allocating these two objects, transfering ownership of A to a member pointer of B, and transfering ownership of B to a member pointer of A? The only possible way to detect this sort of loop would require significant runtime overhead during any transfer of ownership. And that, of course, doesn’t mean it’s inexpressible; just that runtime errors will be raised. The weak/strong/reference pointer design will reduce errors and mistakes, yes, but it doesn’t guarantee that garbage will never be generated. And it becomes useless as soon as you start delving into larger scale real world applications where it simply isn’t possible to provide a single owner who will know when to delete the object. (What happens when the owner thinks the object is ‘dead’ but some background task is still using it? What happens when you have a user-facing scripting language that doesn’t understand weak/strong semantics, and it shouldn’t because that’s semantics the user shouldn’t be forced to deal with?)
And null pointers inexpressible? How then do you possibly have code that searches for objects and has the possibility of not finding anything? (without adding exceptions everywhere, which is a very gross, inefficient, and poor design strategy; exceptions are for exceptional circumstances, not perfectly normal runtime behaviour.) One of my least favorite C++ behaviours, for example, is that the C++ string class has no notion of NULL. You have empty or not empty. Any code which must then return a string, and possibly have nothing to return (common in real world apps), is forced to return extraneous values solely to indicate this situation. This makes code ugly and unreadable, especially in languages that have no concept of a tuple (and even then, it’s usually not pretty). Depending on the string implementation, it’ll also still require extraneous allocation of empty strings.
If you want to avoid NULL pointer dereferencing problems, it may be better to just add compiler support to detect when a pointer can be NULL, and raise warnings in such a situation. For example, dereferencing a pointer after it was assigned NULL should raise a compile time warning. Function parameters should be able to specify whether they accept a pointer to be non-NULL only, and passing possibly NULL pointers to such functions can also raise a warning. The “type” of any pointer in the compiler can simply keep along with it whether it knows the pointer is NULL (you assigned it NULL), whether it knows the pointer is non-NULL (you assigned it the value of another non-NULL pointer or function return that is specified as never being NULL), or is possibly NULL (compiler isn’t sure). Any code inside of tests that check if the pointer is NULL will have a different idea of the pointer’s NULL state. (Complex conditionals can just leave the pointer type as “undetermined”.) What this means in the end is that calls to functions which can possibly return NULL will always result in a warning when that pointer is dereferenced unless there is a previous test or code path that ensures that the pointer cannot be NULL. For example:
p->do_something(); // warning: p could be NULL
pointer p = some_function();
if (p == NULL)
return errror;
p->do_something(); // no warning; p can’t be NULL here
pointer p = some_function();
if (p != NULL) {
p->do_something(); // no warning; p can’t be NULL here
}
p->do_something(); // warning: p could be NULL
// safe_function’s signature states that the return value
// can never be NULL. of course the compiler will do
// check in safe_function’s implementation to ensure this
pointer p = safe_function();
p->do_something(); // no warning; p can’t be NULL here
pointer p = some_function();
if (p == NULL) {
if (value == something)
return NULL;
p->do_something(); // warning: p is definitely NULL
}
p->do_something(); // warning: p could be NULL
// no_null’s signature states that its argument cannot
// be null. null_ok’s signature states that its argument
// can be null.
pointer p = some_function();
no_null(p); // warning: p could be NULL
null_ok(p); // no warning: doesn’t care if p may be NULL
if (p != NULL) {
no_null(p); // no warning: p can’t be NULL here
null_ok(p); // no warning: doesn’t care
}
p.s. Advogato, why do you not understand that text inside of <pre> tags should not have whitespace and paragraph markers added to them? The whole purpose of <pre> is to preserve formatting already in place.
Zeroconf Explosion
So, not long ago, I was lamenting on the lack of any real progress on getting Zeroconf (Apple Rendezvous) support on Linux. The only decent implementation was Howl, but it still has license issues and an unstable API.
Well, apparantly, there’s been a recent explosion of Zeroconf work. Work as resumed on gmdns (GNOME project), a new project called Avahi at Freedesktop.org has been started, some patches and contributions have been going back into tmdns, a new CLR/C# mDnsResonder project at Novell Forge has appeared, and I’ve seen a couple Java/Python Zeroconf projects on Freshmeat lately.
We’ve gone from the problem of no solid implementations to way too many implementations. Hopefully they’ll all play together nicely. You can have multiple apps/processes using multicast DNS at once, but multiple system-level processes (versus responders embedded in individual apps/daemons) could make administration a pain.
Internet Explorer CSS Media Selection
Hmm, apparantly there is a bug (missing feature) in Internet Explorer (surprise!) where the media selectors in CSS are ignored. Which is odd, as I’ve read in several places that IE supports them. Print outs for our internal accounting app (web based) always end up spitting out all the bits which they shouldn’t be in IE, while everything works fine in Mozilla.
Guess I need to continue doing the old, ugly “printer friendly” version of pages that need to be printed often. *sigh*
Weather Forecasters
So having gotten gDesklets running on my desktop, I added the weather display. Mostly just because the icons are rather attractive, and I’ve got 2.4ghz I’m doing anything important with (web development isn’t very CPU demanding). I have, however, come to the firm opinion that weather forecasters are useless.
Monday, the display said it would thunderstorm wednesday and Saturday. Tuesday, it said Wednesday and Friday would have t-storms. Yesterday (with no t-storm that I noticed) said that Saturday and Sunday would t-storm. Today, it says it will be thunder storming straight through Sunday.
What exactly is the purpose of a fore cast if it changes before the time comes to past?
Linode
After reading harshy’s entry about Linode, I decided to take a look. And was very impressed.
Commercializing UML (User Mode Linux) with a hosting service is a great idea. You get the benefits of a complete unmanged server (i.e., root access) with only shared hosting costs. Of course, the lowest end configurations they offer are all sold out for all (I don’t have very demanding needs; just a basic website, Arch repository, mail list manager, and backup services) and I’d rather not pay for a more powerful configuration if I don’t need to.
If any of you are looking for a decent hosting solution, definitely check out Linode. Great prices, cool service.
RPG Character Levels
A fun discussion is going on on the mud-dev mailing list. The main topic being that charater levels in MMORPGs caused problems for friends who do not join at the same time, or who dedicate different amounts of time to the game. In most cases, the content that is both available to and entertaining for a player is based on the level of their character, or how powerful that character is. A character’s level is generally proportional to the amount of time that character has been played.
So say John starts playing this new online game in June. Then his friend Sally starts playing November. Sally has a new level 1 character, while John is something higher (usually, in that time frame, quite higher). The newbie content available to Sally is too boring for John, but the content available to John is too difficult for Sally’s character.
This means that once a couple of people in a group of friends starts playing the game, there is actually incentive for their other friends to not start playing. They’ll be forced apart, or the friends who have been playing longer will be forced to re-experience the newbie content and generally be bored out of their minds.
Quite a few solutions have been brought up on the list. I’ve been mulling over two myself. The first idea is to simply scale the content based on the player character. Classically, game content has some preset difficulty. For example, the Cave of Tears in the Forest of Ouchies may be designed for characters of levels 20-30. Characters below that range will die too quickly and easily to have fun playing there, and character above that range will have no challenges or substantial rewards. With my solution, content would have a much large range of appropriate levels, and the content would alter itself based on the character levels therein. For example, a lower-level character in a region will be able to cause more damage and take less damage than a higher level character. These two characters can even fight side by side without too much difference in difficulty. Characters which have very large differences in levels (say, a difference of 30 or more) may still suffer from the original problem. This solution would mitigate the problem to an extent, however.
My second solution, which is very similar to some of the others brought up on the mud-dev list, is to simply down play levelling altogether. All characters will be limited to a certain range of abilities. This of course just tosses the problem out entirely. Of course, it makes obvious another problem; one which has always existed, but which has been buried away in current systems.
This new problem is the lack of motivation to play. If you have little room to move in terms of raw character power, why play at all? In almost all current MMORPGs, there is pretty much one and only one point to the game: wander around and kill things to gain experience and equipment, thusly increasing your power level so you can find new and more powerful things to slay. Honestly, it’s an incredibly boring and thoughtless cycle, and is the primary reason I don’t play MMORPGs. When the whole point of the game is itself fairly pointless, why play?
The answer, I believe, is to create more of a story in the game, and involve players in those stories. This is done by expanding the quests in the game. Classic RPGs are comprised largely of Fed-Ex or Slay style quests which are, respectively, tasks involving finding some item and returning it or killing some monster. The “intricate” quests in these games are generally just combinations of the two above, with perhaps some clever dungeons or puzzles tossed into the mix.
More intriguing story quests can be possible, however. These story quests can involve more intricate quests; for example, learn some information, protect an important NPC, play an assist role in another NPCs quest, infiltrate an organization, etc. These quests have as rewards not only wealth, but also standing and social networks. Complete an important quest for the Duke of Alara and earn the respect of the Duke, and perhaps a favor from him. Furthermore, this relationship can be carried further increasing his trust, or other plots/quests can unfold in which you betray this Duke.
A player who has been with the game for some time may not be significantly more powerful in raw numbers than newbies, but they’ll have a larger social network and recognition. If then a friend joins the game some months later there will be no artificial wall between them. The new player (Sally) will have little to no social standing, but the original player (John) can bring her along on his quests, since lack of raw power won’t be a real problem. And, during these quests, Sally will be building her own social network by being a part of the plots John already had access to.
The trick then becomes making these plots. Even a large staff will have difficultly keeping the world dynamic if they must do it manually. Especially when you consider that any important NPC could be killed off at any time, or that a quests success or failure can have immediate consequences. (In current MMORPGs, NPCs generally just “respawn” when killed, making their death entirely meaningless, and quests have no real impact on overall plot.)
The game system itself is capable of managing these plots, however. The problem isn’t even that complex, I believe. The first part is to generate the people in the world. The designers probably have a world built, a history, important figures, etc. This information is provided to the system. From there on, the game can, when needed, generate new NPCs, and manage the social maps and networks in the world. For example, if the Duke is killed, then perhaps the King will promote someone else to his position. The game can even schedule in game events for these occasions, so players can attend the promotion. These events can then be used in plots themselves; perhaps a courtier who wanted that Duke’s position sends letters to some of the PCs who have good relations with him to assassinate the newly appointed Duke at the promotion ceremony.
All in game plots and relationships between both NPCs and PCs can be kept track and used at any time to generate new random plots. The game masters and designers can also introduce new planned themes and plots as well using the information the system collects for them. Very one-on-one interaction can occur with each player, allowing them to have very direct impact on the world, giving them direct rewards and consequences for their actions.
We Are All Sheep
The instructions are: Grab the nearest book, open it to page 23, find the 5th sentence, post the text of the sentence in your journal along with these instructions, and then get a life.
She rose swiftly into the air, and the warrior, deprived of his target, found himself momentarily off balance.
Bugs Build Character
Or, should I say, bugs during character building. AweMUD has had a bug in the 0.21 release that had a rather major (bad) affect on character creation (it didn’t work if you selected one of the two most common races), and nobody had informed me until just last week. Yuck.
I want a test framework, but I’ve no idea how to actually code one. I don’t imagine it would be easy at all. The test framework would have to start the sever, try some thousands of combinations of input (and that’s just for character creation alone), parse the output (which is usually fairly clear English mixed with human-intended layout/menues; not something easy to parse programmatically), deal with the fact that the intended output changes a lot as the text is refined and made to read better and such, deal with the fact that the codebase is still under heavy development, deal with the intentional randomness in the system, etc.
I honestly think the only test “framework” that is feasible is to have enough users hammering on the code that common big “hey look at me” kinds of bugs are caught early. Which isn’t itself all that feasible.
As a means to the end, though, I’ve gotten the test server for AweMUD to rebuild from the Arch repository once every couple of days, in order to ensure that the test server is something worth testing against. Which is good.
DistCC and CCache
I setup DistCC and CCache today to see how well they work. Both were rather easy to setup, aside from having to get my Fedora 1 compiler onto my Debian Sarge nodes. (Not that hard, really.)
ccache will help a lot given how I often have several trees of AweMUD I work on (yay Arch!), compilation times already are cut down quite a bit thanks to that. I’m not too sure how much distcc will help me, though. Both at work and at home I have one fast machine (my workstations) and a ton of very slow and over-worked server machines.
Two changes to distcc would be quite useful that might improve the situation for me. The first are the Apple zeroconf patches. If I were to install distcc on all the spare machines floating around, trying to maintain DISTCC_HOSTS would be a nightmare. Second, the load balancing would be nice. I.e., if machine X is very fast and machine Y is very slow, send jobs to X first, and only to Y when X is full (or it has slowed down due to load).
Another nicety, which I’m not sure how to implement on my own, is to have make automatically use the -j (# of jobs) option when distcc is being used, and not use it when it isn’t. No idea how to do that automatically, other than make a make wrapper that both checks the environment variables for CC and CXX, and/or looks into the target Makefile to see if it has CC or CXX set to something with distcc. And then of course to figure out automatically how many CPUs we have to know what -j value to use. (A command line option to distcc to query alive nodes and compute some decent output for this option, coupled perhaps with the load balancing feature above, would be great.)
Ouchie
Dear gods am I sore. Very eventful couple days on the LARP field. Yesterday afternoon five hill giants attacked our keep, which wasn’t very pleasant. The “stepped” over the walls and got in no problem. (This is played by the NPC players declaring that they are stepping over the walls, and we then have to let them in the gate.) The simple fact that we were “fighting” at all was a bit of anomoly, because one couldn’t really turn away the spears of fiften foot giant. Given that all “monsters” are just regular people though, of course, there was some actual battle for a while. I was holding off one giant on my own fairly well, until the two behind me finished off some companions and proceeded to spear me. My friend, the captain of the guard, was the last standing (mostly due to the incredible amount of armour he was wearing) but even he fell under the might of five giants. I mean, come on, the out come was pretty much a given.
This day I was accepted into a military company, which among other things means I now have to have responsibility and purpose, which kinda sucks. On the other hand, it’ll increase my available resources. Guess I’ll see how it works out. One thing I’m not happy about is that now I’m being required to learn to use a shield (it’s like a chain on my arm, and doesn’t help me much given my prefered style - quick and lite), and furthermore the military company’s colors/standard are blue and yellow which clash horribly with my black and maroon outfit and gear. Hopefully I can get out of the shield bit, and I can live with having the standard on a cloth bit hanging from my belt (not sure what those are called; most of the house members have similar bits of cloth on their belt though.)
I took a serious head shot yesteday. We were doing night fighting (I was a giant acid-secreting ant; more fun to play than it sounds) and I had several people battling me. One of my assailants swung hard, my head a bit low, and I took a direct hit to the forward. I usually make a big show of falling over when I die as an NPC (it’s more fun for the players, and I’m rather good at controlled collapsing, due to some acting parts I’ve had in the past, so why not?) but I didn’t need to this time. It was all natural. Smack to the head, eyes crossed, I sword the world rotate around me and smacked into the ground. Rather comical to witness, I imagine. Hurt like a son of a bitch, though. Still have a tad bit of a head ache. On the upside, I was quite alright to continue playing, played another ant not 5 minutes later, and played some trolls not long after that.
Anyways, this is all rather not FOSS related, and you Advogatoans are probably not interested in reading about it, so I’ll lay off the subject for now. Don’t expect that to last, though. ;-)