28 Nov, 2014, Lundex wrote in the 1st comment:
Votes: 0
So I picked up a copy of lama by milkmanjack. A mud built in lua, and attempt to play around with it. So far I don't have much to show for it aside from an ASCII map, an effect system that uses the class like an object, similar to how an LPC mud handles it.

So I thought about if I continued down this route and used classes as objects, like how its handled in LPC. How successful it would be and what problems I would run into. So far the main issues I hit is crashing the mud over errors on my end. Hotbooting the mud after a successful change in code has its benefits along with building classes to act like objects.

But I'm just curious as to what other have to say about this type of route.
06 Dec, 2014, Nathan wrote in the 2nd comment:
Votes: 0
This, I assume -> https://github.com/milkmanjack/lama

It's very unclear what you are proposing and why you would do it. A little more detail about what you are actually doing and why you want to do it would be helpful. What do you mean by 'classes' as 'objects'?
07 Dec, 2014, Lundex wrote in the 3rd comment:
Votes: 0
Correct that is the right project. Its a simple as in the project directory it is listed a obj which contains all object-related classes.

I plan on adding to that such as obj.items.Hat or obj.items.Sword, which represents the object when it is instanced. Such as all classes in obj.items would inherit form the Item class.

It will load each class in and allow it to be instanced, and also allows you unload and reload to change objects without having to hotboot(copyover) or shutdown the mud.
05 Mar, 2015, milkmanjack wrote in the 4th comment:
Votes: 0
It's important to note that Lua is a scripting language. It doesn't do much on its own, and isn't capable of much on its own. You can't access any GPU elements, you can't manage memory at a more basic level, there's very little I/O capability. No access to keyboards, mice, audio. Can't access the file system directly (other than writing and reading files).

On the bright side, the fact that it's a scripting language means you can do everything under the sun with it as long as you add an interface for Lua to the interpreter. LuaSocket provides network I/O operations to the Lua scripting language. LuaFileSystem adds file system I/O to the Lua scripting language. There's probably an extension somewhere that lets you create windows and draw using OpenGL or DirectX.

As it stands, since we're talking about a MUD, all we really need is networking, file system access, and a method to interact with entities that have unique attributes (we're talking objects here). If you look at any MUD ever written, none of them do anything that requires anything more than these 3 basic capabilities. Strictly speaking, you don't need objects at all. If you look at the C MUDs, like DikuMUD, they use unions and linked lists to accomplish the whole "separate entities with unique attributes" part.

So no, you should have no problems making a MUD in Lua. If you find there's an operation you need to do but Lua is too slow for it (I dunno, pathfinding over large areas?), you could try to find an extension that helps out with it, or you could even write your own extension if you're knowledgeable (or you could just read up on how to do so).

If you wanted to say, create an exact replica of DikuMUD or ROM, you'd find nothing stopping you. I'd actually wager Lua is easier to manage. I don't know how you'd handle hotbooting in C, but I bet it isn't as easy as reloading all your packages. I assume you'd have to save the file descriptors somewhere, shut the program down, reload the program with some kind of special flag so it knows to reload said file descriptors, then reconstitute them. I don't even know. I've never really worked with sockets in C.
05 Mar, 2015, Nathan wrote in the 5th comment:
Votes: 0
I believe hot booting in C, at least on some UNIX systems, has generally involved forking processes. If I understand correctly, the program (parent) would start a new instance of a newer version of itself (child) which would have access to an exact copy of the parent' memory space (or simultaneous access to the same space) and then the parent would kill itself.

You could technically have a game representing it's entities with a database table and simply using sql calls to retrieve, modify the data in place. In any cAse, you don't need much in the way of "real" objects but you do need aggregate data types

I don't think you can 'save file descriptors' in any meaningful way if you close the program. Your connections would get dropped. You might be able to hand them off to another program or just have network and game be separate processes altogether that communicate back and forth.
05 Mar, 2015, quixadhal wrote in the 6th comment:
Votes: 0
It's not entirely accurate to claim that you can't access hardware or low level things from lua because it's "just a scripting language".

ANY language can access ANY level of what it's running on, provided somebody has coded an API in the language compiler or interpreter to do so.

As far as the idea of a "hotboot", to preserve connections between "reboots" of the game, there are two different ways to accomplish that. The first is what most DikuMUD's do, and it involves saving the file descriptor -> player character mapping somehow, doign a fork()/exec() of the new driver, and then having that new driver call dup2() to initialize new socket structures to already opened and existing sockets via their descriptor. If Lua has these things exposed, there's no reason it can't do the same.

The other is to seperate networking from the game engine and simply reload the game engine in-place. A language like python lets you reload objects from new on-disk code, so as long as you can restore the game object -> socket relationship, there's no reason that can't work.
05 Mar, 2015, milkmanjack wrote in the 7th comment:
Votes: 0
quixadhal said:
It's not entirely accurate to claim that you can't access hardware or low level things from lua because it's "just a scripting language".

ANY language can access ANY level of what it's running on, provided somebody has coded an API in the language compiler or interpreter to do so.


I nipped this in the bud already in my post.

"On the bright side, the fact that it's a scripting language means you can do everything under the sun with it as long as you add an interface for Lua to the interpreter. "

My point was to show that, while Lua can't do much on its own (the packages it reveals are pretty basic), if you start putting extensions in or writing your own, it can do anything C can.

Nathan said:
I believe hot booting in C, at least on some UNIX systems, has generally involved forking processes. If I understand correctly, the program (parent) would start a new instance of a newer version of itself (child) which would have access to an exact copy of the parent' memory space (or simultaneous access to the same space) and then the parent would kill itself.


Interesting concept. I've heard of forking processes before, but I never knew they could have access to the same memory.
05 Mar, 2015, quixadhal wrote in the 8th comment:
Votes: 0
Actually, when you fork() a process, you create an exact duplicate of the memory space. When you exec() a new executable into it, that goes away and is replaced by the new image. However, on unix, files and sockets are all associated with a descriptor. These are not explicitly closed when an exec happens, although the buffers and memory structures associated with them go away.

Hence, you can restore them if you keep track of which descriptor needs to go to which new structure.

For example, a common way DikuMUD's do this is to write out a file with descriptor numbers (integers) and player names (strings). When the new binary is loaded, code is called to restore the association in the file (if present). So, if descriptor 13 was Quixadhal, you'd load Quixadhal's player data into a new player object, create a new connection object and use dup2() to tie the descriptor to the new socket structure, rather than calling open() or connect() on it.

There's a few more details like making sure your select() masks are also right, but that's the general idea.
05 Mar, 2015, plamzi wrote in the 9th comment:
Votes: 0
milkmanjack said:
I don't know how you'd handle hotbooting in C, but I bet it isn't as easy as reloading all your packages. I assume you'd have to save the file descriptors somewhere, shut the program down, reload the program with some kind of special flag so it knows to reload said file descriptors, then reconstitute them. I don't even know. I've never really worked with sockets in C.


As quix has already outlined, a combination of C and Linux actually makes it very easy to bounce the server while keeping your existing connections unaware.

But, having spent some time fiddling with dynamic code changes on both the C and scripting sides of the fence (it's a subject I'm fond of), I think we have a false comparison going on here. There are different flavors of "hotbooting," and reloading scripts / packages may or may not be equivalent to the effects of a classic Diku hotboot.

While keeping the descriptors unaware during a reboot is a neat trick, it doesn't do anything to magically preserve the game state. In other words, if Player A is about to finish off a well-buffed dragon, and you do a Diku hotboot, you are responsible on the other end for restoring their position, and the near-death state of their opponent.

When I was primarily working on my Diku / Circle MUD, I found myself almost never needing to hotboot. Instead, I wrote some additional routines that would help me push changes to over 90% of the code while maintaining the game state.

In my new node.js codebase, I did some quick research to find out that the classic hotbooting trick is not yet exposed, or it may be exposed, but certainly not straightforward to do. Instead, I focused on tapping into the benefits of a scripting layer. There, I discovered that if you care about preserving the game state (and also about performance), things are almost as hard as in C. Reloading a script / module / package is the easy part. Updating existing entities to reflect the latest object structures while still maintaining their previous state, that's the hard part.
0.0/9