17 Jun, 2014, quixadhal wrote in the 61st comment:
Votes: 0
LOL, not me!

The muds I played were original Diku, Silly, Smaug, and a couple of LPMUDs. I remember thinking Rom's character customization was pretty neat… but the one I tried took it to an extreme, so there effectively wasn't a point to classes any more, so I didn't play it long.
17 Jun, 2014, syn wrote in the 62nd comment:
Votes: 0
A long time ago yes.

// seems to operate much like C from my reading so I think that is the biggest of that particular issue in converting it, changing from / to // for divisors
17 Jun, 2014, Davion wrote in the 63rd comment:
Votes: 0
syn said:
A long time ago yes.

// seems to operate much like C from my reading so I think that is the biggest of that particular issue in converting it, changing from / to // for divisors


Ya, Quix went to work and switched over most of the codebase so far. I hit a snag with imports. They're getting pretty unwieldly. I'm probably going to have to move most of the handler functions into separate files and extend the CHAR_DATA class with them as methods. Then the class would be self aware and wouldn't need all the imports.

Here's hopin anyways ;)
17 Jun, 2014, quixadhal wrote in the 64th comment:
Votes: 0
refactoring isn't a bad thing anyways. Visual studio seems to have some awfully nice tools for that.

I already like the "global rename" which is smart.. not just a pattern matching thing, it recognizes all the tokens, so you can rename a method like FooBar as Foofoo, and it won't touch a variable named FooBar, or a function named FooBarPfft, or even a method named FooBar in a different class.

Good stuff. I just wish it would run the program in a VS panel, and not a tiny little cmd.exe window.

BTW: I'm using Visual Studio 2013 Express… which is the free version. No idea what anyone else's desktop is like, but if you run windows 7 or 8, you might give it a whirl.

Basically, follow this link for directions… https://pytools.codeplex.com/wikipage?ti...
18 Jun, 2014, Kelvin wrote in the 65th comment:
Votes: 0
I've got some open source PyCharm licenses for Evennia, but could probably toss a few towards this effort if any of you want to give it a shot. It's widely acknowledged as the most powerful Python IDE on the market, but it does eat some RAM. Shoot me a PM if you're interested.
18 Jun, 2014, Davion wrote in the 66th comment:
Votes: 0
quixadhal said:
refactoring isn't a bad thing anyways. Visual studio seems to have some awfully nice tools for that.

I already like the "global rename" which is smart.. not just a pattern matching thing, it recognizes all the tokens, so you can rename a method like FooBar as Foofoo, and it won't touch a variable named FooBar, or a function named FooBarPfft, or even a method named FooBar in a different class.

Unfortunately, I need to convert foo_to_bar(foo,bar) to ch.foo_to(bar) so this probably wouldn't help. However, I most likely wont touch variables/fucntions/methods as the regex is pretty explicit. Only thing I keep gettin is the header commet :P
quixadhal said:
Good stuff. I just wish it would run the program in a VS panel, and not a tiny little cmd.exe window.

BTW: I'm using Visual Studio 2013 Express… which is the free version. No idea what anyone else's desktop is like, but if you run windows 7 or 8, you might give it a whirl.

Basically, follow this link for directions… https://pytools.codeplex.com/wikipage?ti...


Is the reason it doesn't run in the vs panel because it's not Iron?

I've been using Sublime Text 3 now for awhile since my pycharm license expired *nudge Kelvin*
19 Jun, 2014, quixadhal wrote in the 67th comment:
Votes: 0
Yeah, that'd be my guess. IronPython is written in C# and pretty tightly integrated into the whole .NET platform. But IronPython is still stuck in Python 2.7.x… I figured it's only reasonable that Python 3 is the way to go, since at some point the 2.x series will become "legacy" and nobody will want to do the work to port it all the 3.x at that time.
20 Jun, 2014, Davion wrote in the 68th comment:
Votes: 0
The refactoring is done. handler.py is but a shell of what it used to be. I'm commit what I had and now I'm just picking off all the misses. There's a couple imports I missed, and a few functions missed changing to methods. Not much changed. char_to_room(ch,rm) is now ch.to_room(rm). Only major name change would probably be affect_to_char is now ch.affect_add(), ch.affect_rem(). Looked nicer and fits along with ch.affect_join() and ch.affect_strip()
21 Jun, 2014, quixadhal wrote in the 69th comment:
Votes: 0
Very good. I'm fixing some undefined reference issues and think I'll rewrite do_pose()…. the way it (fails to) work now relies on pointer arithmetic that is specific to the way arrays in C work. I think redoing the pose table as a normal dictionary should be much simpler, and the only place that seems to directly access the table is do_pose() itself.

Also, new IDE (PyCharm) seems to be a bit more solid with respect to python that visual studio's plugin. I'm giving that a try to see if it does things smarter and doesn't waste several commits eating our code. *grin*

Thanks Kelvin!
22 Jun, 2014, Davion wrote in the 70th comment:
Votes: 0
quixadhal said:
Also, new IDE (PyCharm) seems to be a bit more solid with respect to python that visual studio's plugin. I'm giving that a try to see if it does things smarter and doesn't waste several commits eating our code. *grin*

Thanks Kelvin!

Loving "shift+shift" and shift+f9. Gloooory! Almost makes up for the terrible boot times ;)

Thanks Kelvin!
22 Jun, 2014, syn wrote in the 71st comment:
Votes: 0
i love pycharm so far, it helps find a lot of issues, and is just great in general
23 Jun, 2014, Davion wrote in the 72nd comment:
Votes: 0
Well the commits are getting smaller code-wise. A lot of kinks have been worked out. I was online for about a hour pluggin away without any crashes or noticeably weird things. I've uploaded what we have as the official alpha release. AFAIK all code is translated and should be functionable. The translation problems should be few and far between hopefully!

If you notice anything let me know. I'm going to start planning for a Beta release which should hopefully include most of the things ROM could need for rapid development.
23 Jun, 2014, Davion wrote in the 73rd comment:
Votes: 0
Not entirely so sure I want to add this to the working copy, but I've been playing with this for a bit with promising results.
import os
from importlib import reload
import act_info
import interp

#dictionary of files to track. will be key'd by file name and the value will be modified unix timestamp
tracked_files = {}
def init_file(path, module):
#called by init_monitoring to begin tracking a file.
tracked_files[path] = (os.path.getmtime(path), module)
print("\t…Tracking %s\n" % path)

def init_monitoring():
#Called in main function to begin tracking files.
print("Monitoring files for modifications.\n")
init_file('act_info.py', act_info)

def poll_files():
#Called in game_loop of program to check if files have been modified.
for fp, pair in tracked_files.items():
mod, module = pair
if mod != os.path.getmtime(fp):
#File has been modified.
print("%s has been modified\n" % fp)
module = reload(module)
reload(interp)
tracked_files[fp] = (os.path.getmtime(fp), module)


I took a look at donky's livecoding to see if I could get it working but no such luck. Seems some packages were depreciated in python3.0. This appears to be cross platform as well. One problem is old pointer objects are not updated to the new ones. Fortunately, targeting act_info is fine as long as you reload interp.py (as its probably the only thing that imports it because do_funcs are methods). I'm not so sure we'll want to do this on files that are imported by many things. However, going forward as long as your concious of this fact newly developed files should be fine. There's gotta be a way to store dependencies for these files. If that were the case you could just reload the whole dependency tree. However, I did attempt to reload merc and it failed, I didn't try much beyond that so not sure if it's an insurmountable problem or not.

I'm going to play with it more to make sure there's no memory problem. I noticed a jump to around 30mb of ram after the first reload. Now it seems to hover there.
23 Jun, 2014, Davion wrote in the 74th comment:
Votes: 0
I had great success with this. I went a head and added the first command of the codebase! We now have a reload command. All the act_ files and the handler_ files have been added to the tracking. I'm not sure if more can be add, I didn't try at this point, just wanted to lay some ground work and help speed up the development.

It works very well so far! I had to change up the imports a bit, but as it turns out I understood them wrong. I figured import blah was for when you needed lots from a module or when there where conflicts in the namespace and from blah import boo when you only needed a couple of things with no fear of namespace trampling. Turns out I was wrong and one or the other should be picked with consistency! I've attempted to do this in a few files, but I don't intend to change the "from merc import *" because… well, I don't want to change every bit, function and class reference to merc.blah! Blah that!

TL;DR version
Pyom has an instant copyover that only reloads code and leaves the DB alone.
23 Jun, 2014, Kelvin wrote in the 75th comment:
Votes: 0
Be wary of all kinds of object issues with live reloading. We used to do this with Evennia, but it's almost always a super bad idea due to unexpected edge cases. It's one of those things that is technically possible, but not without plenty of situations where a reload will leave things in a messy state.

Evennia worked around the issue by sticking a proxy process that handles all of the telnet connections in front of the MUD server. The server could then be restarted without ever dropping connections, and without ever running into the sneaky edge cases we were seeing.
23 Jun, 2014, Davion wrote in the 76th comment:
Votes: 0
Kelvin said:
Be wary of all kinds of object issues with live reloading. We used to do this with Evennia, but it's almost always a super bad idea due to unexpected edge cases. It's one of those things that is technically possible, but not without plenty of situations where a reload will leave things in a messy state.

Not sure if this makes a difference but I read the docs and it explain how previous pointer references are left alone. What I've currently done is attached it to files that have automatic loading attached to them. All classic do_functions are added to the CHAR_DATA struct via MethodType after cycling through the command table. I figured as long as I rebuild the links (via calling the load function) I'm pretty safe.

The second set of files that are tracked are pretty similar. They were the handler functions for ROM. They are now members of a class that is added to the primary CHAR_DATA class. I reinitialize all those methods again after an edit is done. So currently the only thing being reloaded are methods that we track in the codebase. I plan to use this only for rapid development.

Kelvin said:
Evennia worked around the issue by sticking a proxy process that handles all of the telnet connections in front of the MUD server. The server could then be restarted without ever dropping connections, and without ever running into the sneaky edge cases we were seeing.


Is there any reason the classic use of execl() didn't work? Python claims it works on both Windows and Linux so I was kinda bankin on using that for a copyover. Something for the more drastic code changes. My current problem wasn't necessarily the dropping of the link but the time it takes for the DB to boot up just to test how an extra new line looks. Do you have any idea just how long it took to get the proper ROM look and feel?! Do you!?
23 Jun, 2014, quixadhal wrote in the 77th comment:
Votes: 0
The big danger in cases where individual objects may keep pointers to old methods is… either the existing object keeps the old behavior, or it crashes if the old function is removed.

I would guess python uses garbage collection, so if you were to update the character class, for example, with a new bug-fixed method, any NEW player logging in would get the fixed version, but any player already logged in would still have an instance of the class using the older version, and those wouldn't go away unless you specifically went through and created new instances for them, transferring all the data over.

It's not a big deal in the typical Diku model, since you tend to reboot frequently anyways. However, if you tried to be fully dynamic so reboots were a rare event, this would start becoming an actual issue that needs addressing.
24 Jun, 2014, plamzi wrote in the 78th comment:
Votes: 0
Kelvin said:
Be wary of all kinds of object issues with live reloading. We used to do this with Evennia, but it's almost always a super bad idea due to unexpected edge cases. It's one of those things that is technically possible, but not without plenty of situations where a reload will leave things in a messy state.


The part where it can get messy, I imagine, is if you have a lot of instancing that is basically cloning. Otherwise, if you are extending prototypes with "behavior blocks" e. g., then you already have methods for updating all the pointers in the instance that are methods as opposed to properties. In the node.js experiment I sometimes tinker with, I've also had to override some performance-eeking method caching to force a module to reload.

In general, this is a great feature for devs to have on their test ports, since it speeds up development, but it should ideally be a last resort on the production port. I've been guilty of using it in production, but that's on a Dikurivative where there's hardly any true instancing, so it works pretty well.

Kelvin said:
Evennia worked around the issue by sticking a proxy process that handles all of the telnet connections in front of the MUD server. The server could then be restarted without ever dropping connections, and without ever running into the sneaky edge cases we were seeing.


This seems to be very similar to "copyover". But can you maintain the state of the game in the process?
24 Jun, 2014, Davion wrote in the 79th comment:
Votes: 0
quixadhal said:
The big danger in cases where individual objects may keep pointers to old methods is… either the existing object keeps the old behavior, or it crashes if the old function is removed.

I would guess python uses garbage collection, so if you were to update the character class, for example, with a new bug-fixed method, any NEW player logging in would get the fixed version, but any player already logged in would still have an instance of the class using the older version, and those wouldn't go away unless you specifically went through and created new instances for them, transferring all the data over.

It's not a big deal in the typical Diku model, since you tend to reboot frequently anyways. However, if you tried to be fully dynamic so reboots were a rare event, this would start becoming an actual issue that needs addressing.


From what I've been able to gather from my testing is the way I bind the method in the first place it binds to the class and not the individual objects. Even if one were to call from a previously attached pointer it shouldn't call the old class methods, especially since those are all updated once reload() is called.

I've actually got some pretty astounding results, and I'm able to just drop functions right into the codebase. It's awesome! Gunna try and not get to far ahead of myself but so far it looks good.
24 Jun, 2014, syn wrote in the 80th comment:
Votes: 0
Hey Davion,

I have bug fixes n things for a pull request if I may, general change list:

Added handler_log to begin the underpinnings of the log system. Currently you can add @logger("Debug") as a decorator for a function and it will provide a safe environment for function execution, if fails it will print a nice stack trace + env variables and inform the ch.

Current output is this:

Exception: <class 'NameError'> name 'myfail' is not defined
Frame Trace - File: D:\GITs\Pyom-Python3\Rom24\pysrc\act_info.py Line: 325 Function: do_socials Offending Code: g = myfail(y)

Local Env Variables:
social : <merc.SOCIAL_DATA object at 0x00000000049D5E10>
col : 0
self : Syn
ch : Syn
argument : ''

Also added numerous bug fixes, and tweaks to be in line with Python PEP 8 code format standards. (this will take a while, but started in on some files)

Fixed/cleaned several modules import areas.

Added liquid table, so now it actually will exist, and provide liquid information, yay firebreather!

added in the trust level->name defines so now IS_TRUSTED checks will actually work.
60.0/93