Efendi and Sigma
I’m very happy with Efendi. I have a little file locking bug in my sqlite database that occasionally hiccups, but generally it’s stable and there’s nothing I would add. Well, for the sake of completeness there is actually no comment editing facility once the comment is approved, but for me that’s not important.
Sigma is really going nicely. I am eager to get it on my system sometime soon. My job will be to jump in after Meta finishes the combat core. I have learned a lot more about Python, and I know some design patterns that will straighten out mistakes I made years ago. We’ll get the codebase nice and tidy and start looking at the last few big things to do.
Unless you’ve dabbled in what I might call stateless scenarios, a lot of this thinking is very peculiar. When I say stateless I mean: there is no way to “pause” a MUD, because it’s a world rather than a game. If one player wants to stop, what about everyone else?
A good example of the illogicality of the big blockages is shopkeeping. If you think about going to the store in Secret of Mana or Final Fantasy, you probably expect a tunnel-vision scenario: the shopkeeper engages you, you say what you want, you pay, sell something, and get out. Seems like a small thing.
Again, you might have three people in the room in a MUD scenario, and getting that individual attention becomes either difficult to implement or could even cause a break in the “reality” of the world.
Also, if somebody comes in and attacks you, you had better be able to know. How do I manage that state? Are you in state SHOPPING
, and a certain list of actions bring you back to state PLAYING
? But you don’t get any world action updates until then? That’s hardly realistic or reasonable. Screwing with player state (meaning, effectively pulling a player’s perception or even existence out of the world for some reason), is frowned upon because it takes away the activeness of the surroundings. You’re back in Zelda, where everybody only ever talks to you.
But how do you manage a shopping scenario where people are entering and exiting the room while you’re looking at the product list? How do you define who a shopkeeper is in a game, and can a human player become one?
The fact is, it’s probably best to have a ‘shop’ command, which can take the name of a character to be specific when we have multiple shop keepers. This prints out a product list and a ‘buy’ or ‘sell’ command completes the transaction. If you don’t like scrolly text, set a notification threshold to ignore player movements and conversations for a while.
I think a ‘vend’ command is nice, where you put a tag on items that are currently being sold by a character. This allows individuals to become shopkeepers.
Then, you have to think architecture: I think it’s best to have shopkeeper be a ‘persona’ where a character automatically puts a ‘vend’ tag on any item added to his inventory. This ties up a lot of loose ends in one swipe, as a sold item would be automatically tagged as it entered the inventory of the purchasing shopkeeper. Another option would be to have a kind of special case somewhere:
if character == shopkeeper then ...
Sigma has always been about putting a system around things to make sure good logic can be good logic throughout the game. For me, it’s almost always better for an automated action to simulate a typed command:
character.queue('go west')
rather than use some library command:
move_character_between_rooms(character, room1, room2)
The result is the same, but let the command interpreter figure out what to do about moving a character. Because as the game gets more complex, moving a character becomes a highly controlled activity: checks to make sure the player is not asleep while trying to move, not fighting (or if allowed, that needs to be an attempt to run away), not dead, not logging in, and if there are followers the followers need to be moved as well. You tear the game asunder if you start calling brute-force backend functions to do these tasks.
Circle, the old premade engine we used in high school, didn’t have this rich of a backend interface. I struggled to make things work because I overlooked necessary checks when extending the system.