Tuesday, July 6, 2010

Releasing Golem

Well, I've done it. =) I've released a new product over at ShadowTeq, called Golem, which is a brand new crafting bot. I built Golem a little differently than I've built products in the past - I departed from the tired tab-based single-form format that I've been using for years in EverHarvest, Market Sniper, AutoLotto, and even VanCraft.

The new system is something closer to a wizard view, where you select the task you want to perform and then are guided through how to perform it. Building this from scratch was a bit of a challenge - I ended up building a simple view engine, which hosts the form itself as well as provides View lookup services for the pages themselves. It works well enough, and provides a good deal of separation between the UI concerns and the rest of the application.

Essentially, each page of the application is a 'view,' implemented as a UserControl. These are dynamically created when they're needed, and destroyed when they're no longer displayed. This means that any state that needs to be displayed needs to be saved somehow - I solved this by making the application's controller accessible from the views themselves. No, this is not my ideal mechanism - but I didn't really feel like building an MVC framework myself, and I didn't want to use anybody else's.

Anyway, about Golem: the crafting engine itself was built using my new automation framework called Eidolon. Eidolon is by leaps and bounds more advanced than any other framework I've developed for these purposes, and makes building automation engines a complete snap. Just to give you an idea, the entire crafting engine for Golem takes up maybe 600 lines of code, and took me a few hours to bang out and make run well enough for beta. That's an incredibly small amount of time and code! Of course, I've been working on Eidolon for months - tweaking it, building prototype projects, etc.

One part of Eidolon that I'm particularly proud of is something I call Wraith. Wraith is my new microthreading / workflow library based around C# compiler generated state machines, via the 'yield return' keyword. Using Wraith has allowed me to build the crafting engine without having to worry about things like pausing or canceling early, because the tasks that the engine performs are done so in tiny pieces. Wraith essentially lets me write long blocks of code, but when they're executed they get broken up into small tasks, with pausing, quitting, and other code interleaved between the tasks.

One way I take advantage of that is in tell notification. Tell Notification is a feature that, while you're character is crafting, if you receive a direct message from another player, Golem will let you know about it. While important, Tell Notification has *nothing at all* to do with crafting - so it didn't make sense for me to build it directly into the crafting engine. So what I did was build a Wraith Service, which lets me hook into the task execution portion of Wraith, and have that Tell Notification service perform all the work of listening for these tells.

Alas, I'm rambling. All in all the release went well, and people are picking it up. There were a rocky couple of days where people were having trouble, but due to the diligence of a couple of my customers (thanks guys) we were able to beat the bug. Turned out I wasn't checking log lines for the possibility of null after pulling them out of the log - this was causing Null Reference exceptions, and crashing the program. Tough bug to find after all the obfuscation... =P

So far the ride's been fun - I'm sure it'll only get more interesting as time goes by. =)

Thursday, June 17, 2010

...

Something new is coming...

Tuesday, June 8, 2010

Silence is deafening

So it's been almost 4 months since my last post... To be honest not much has happened that's been worth posting about. Work has been crazy intense lately - I'm responsible for 3 projects, all of which need to be done *now* - plus there's keeping on top of ShadowTeq. EverHarvest is still going strong, continuing to pick up users at a slow but steady pace.

I've been working on a new product that I'm not ready to publicize. That's part of the silence - timing is critical here, and I feel that if I announce it early I'll spoil it. So I'm going to maintain radio silence on that for a while. Testing for it is ongoing - it's in the hands of several of my most trusted users - and initial reports are encouraging. All in all I'm excited for the future, but I'm anxious as well.

Thursday, February 18, 2010

ShadowTeq, EverHarvest, Expansions and Operating Systems

First: ShadowTeq is up and running! Paypal integration has been finished for a couple weeks now, and purchases have been coming in. Thanks you guys by the way - you've all been extremely patient!

There was some initial confusion over the changed subscription and licensing scheme. I noticed a couple people have purchased licenses, but not subscriptions, and therefore ended up using the trial. I have since then reworked the purchasing system to prevent you from buying a license unless you have an active subscription.

Meanwhile, a new EQ2 expansion has been released - "Sentinel's Fate". I haven't had much of a chance to check it out yet. A very friendly user has donated an expansion key, however, so I'll be in there seeing the new stuff with the rest of you soon. That expansion release made some changes to the client code - particularly the code I hook to find the current target name - so this update took me a couple days. Everything's up and running now though so that's the good news.

Speaking of good news - while I was at it, I finished off the last of the reflection code that was preventing me from using the new obfuscation software that works with Windows 7. I was using reflection in several places in EverHarvest - the main UI, the save files, and a few other places - and obfuscating code with reflection in it requires some pretty advanced features. The obfuscator I was using belonged to Michael, and wasn't compatible with Windows 7, so I needed to change. With the old reflection code replaced, I fired up the new obfuscator and lo! it worked! Windows 7 is now officially supported, in all its versions, in both 32- and 64-bit!

Very soon I'll be starting development on a new ShadowTeq harvester. Details on a beta test will come within a month, I'm sure. =) I'm going to experiment with a limited beta test - very small numbers to start with, to grow over time. More details on this to come. =)

Thursday, February 4, 2010

Nearly done setting up ShadowTeq!

Good news everybody! ShadowTeq is nearly done being set up - which means, I'll be monetizing EverHarvest again. The past several months have been interesting - free working EverHarvest for all - but soon I'll be resetting the trials and setting them back to 5 day expirations. After that, you'll have to buy a license (unless you already have one) and subscribe to the site in order to use it.

On my mind is the subject of what exactly EverHarvest is. Most people call it a harvest bot - but I don't personally like that terminology. I prefer harvesting automation software' to harvest bot', but I recognize that there isn't much I can do to change perception. The reason 'harvest bot' is the wrong word for EverHarvest is that it calls to mind unprofessional script-like software, written poorly, unsupported, and requires arcane tricks to get working. That's the same reason we don't call EverHarvest a harvest macro, harvest script, or similar. It's more professional than that - more user-friendly.

Ah well. Just ranting. Take a look at ShadowTeq and let me know what you think. =)

Tuesday, January 19, 2010

Busy busy!

Wanted to post another little update (and then hopefully get back to the programming content, finally!) - the job is going wonderfully; almost too good, I think sometimes. I'm starting to be seen as the go-to guy with the tough problems. In particular I'm getting the things that *have* to go out *now*.

This is great though - it's how I like to work, under a deadline. Deadlines put pressure on me to deliver - if I had no deadline, I'd meander on the project, trying to make it as clean as possible, put off the hard or tedious parts, and in general not deliver much. This is a big part of the reason why I still haven't gotten Paypal integration going on ShadowTeq - it's not that I'm lazy, I've just got no deadline.

So I need to give myself a deadline with the Paypal stuff. Having a busy family life is no excuse - the kids are in bed by 9 anyway. I'm setting the deadline to the end of this coming weekend - so, the 24th. I'm posting this publicly so that I'll have to take some accountability if I fail.

Wednesday, December 30, 2009

Announcing ShadowTeq!

ShadowTeq.com, the new home of EverHarvest, is officially online! New purchases and license extensions are still currently disabled, but I hope to rectify that situation very soon. The new EverHarvest launcher is available from the site, so I can once again provide updates myself, without any of the lame manual downloading that was necessary over the holiday season.

At present I don't plan to use forums for customer support; I'll be using a combination between email support, a knowledge base, and comments on knowledge base articles to provide help and support. The infrastructure for this is currently online, but I haven't written the articles yet. These will come very soon as I start converting such things as the original EverHarvest guide, and some of the common problems encountered from the old forums. In the meantime, if you require support, email me directly from the email address listed on the ShadowTeq site.

Thursday, December 17, 2009

Life Update

So almost two months ago, I found a new job.

After I came back home from Seattle, my wife and I stayed at her dad's house - he helped us to get back home, provided a place to stay for us and our children, on the expectation that it would take me around 2 months (in the current economy) to find a job. I looked daily - I started out with a narrow focus, looking for software development jobs so that I could continue doing what I love to do. During this period I had two telephone interviews for Blackbaud, and one for BenefitFocus; both of which considered my lack of team development experience as a reason not to hire me. As the weeks ticked by, I broadened my scope - networking jobs, PC repair jobs. After my first jobless month I began looking into contracting work, and had some small successes there with another contact of mine in NYC - but it wasn't stable or steady enough to earn me a living.

I began to lose hope in finding a job in my field. At around the second month I began looking locally at jobs in computer retail outlets, where at least I could use my knowledge to help me sell stuff. None of the local houses were hiring, and neither were the chains - Best Buy, Circuit City, etc. I began to consider retail in any form - the local mall, other places - but none were hiring (or, at least, hiring someone with no retail experience).

During the fourth month I began to scrape the bottom of the barrel. Gas stations, fast-food, Target or Wal-Mart. I had a fairly promising interview with a telemarketing company, which might have become my fate if not for Tasha's diligence - you see, she never gave up looking for programming jobs in the first place. Throughout this whole process she would send me a list of programming jobs to apply for - and although I had already given up hope of getting one, she would hound me until I applied anyway.

Thank God for Tasha.

Near the end of the fourth month - after Ta's dad had told us that he wanted us out, kids and all - I got an email from a corporate recruiter for a multi-national military contractor who was interested in interviewing me. I wasn't terribly excited - I figured it would be another dead end, but I called her anyway. She asked me the standard bits - questions about my experience, schooling, etc. After we were done she asked me to come in for an in-person - I of course accepted, but still wasn't optimistic. The in-person is usually where I bomb; I get nervous, and when I'm nervous I sound like I have no idea what I'm talking about.

But there was one plus-side: she told me that my interviewer wanted to see a code review. Here at least I would have the chance to prove I'm capable of programming, even if I stammer like an idiot through the interview. So that's what I did - specifically, I spent about 30 minutes building a simple recursive descent expression parser and evaluator in C# (very similar to the one I wrote in F#), and send that on. It ended up around 150 lines or so - 3 printed pages, so I figured it was large enough to serve as a sample, yet small enough to evaluate.

The interview day came, and off I went. I met my future boss (Dan) and his senior developer, and had the interview. We discussed my resume, my experience, my schooling. Soon we came to the code sample - which Dan had printed out and brought with him. At this point I was still quite nervous, though Dan had a very open demeanor - but when the code sample came up, I knew that this would be the thing to either make me or break me, as it were.

I shouldn't have worried so much - "Quite pleased" I believe the words were, describing the code sample I submitted. He asked me why I picked that particular topic, if I'd used that piece of code in a project - I told him no, but I've always been fascinated with compilers and languages, so since I wasn't given a specific assignment I figured I'd display that interest in the code sample. The more we talked about the code sample, the more they seemed to like me, and the less nervous I became.

After that we talked about technology, the trends therein, and how closely I follow new developments, and that sort of thing. I asked about the team, who I'd be working with, and where I'd fall in the spectrum. Surprisingly, he told me that the entire team is largely made up of lone coders, like me, who, also like me, are looking for more than the lone coder experience - they, like me, want to build a cohesive team that works together, rather than as separate entities on separate projects.

I was to suffer for a week before I found out whether I got the job or not. After the interview, I was stoked - this was a company that seemed to really get it, and was trying to put together a solid development team. I badly wanted this job - not just because I needed it, but because I truly wanted it.

Needless to say, I got the job. =) So this is where I work - and so far, it's been a blast. =) The people are great, the work is stimulating, and the company is stable - growing, in fact, despite the economy. I joined sort of at the ground floor on this particular team, and already I'm helping to set policy and precedent regarding how the team will work. I'm part of a committee tasked with developing a team-wide code standard, and along with our senior developer I'm helping to bring everyone up to speed on .NET (we have a great variety of development talent and experience, but not much .NET).

So there you have it - that's been my life for the past 7 weeks. =) Things are looking up for me, and despite the fact that I write code all day, my interest in it is actually *growing* rather than shrinking, as it did at my last place of employment.

Monday, December 14, 2009

The Future of EverHarvest

Michael and I have decided to separate our business - EverHarvest is no longer being hosted on his site or supported via his forums.

This does not mean, however, that I will not be continuing to keep it running. At present, the authentication service that allows users with active licenses will continue to run on Michael's site, and I will be effectively extending licenses indefinitely - that is to say, if you purchased an EverHarvest license at some point in the past, then you will very soon be able to use it regardless of whether your license is expired or not. This is a temporary measure however since license extension purchases have been removed from Michael's site.

I will continue performing updates to EverHarvest that are required as a result of EverQuest patches and client changes. In the event that a patch occurs before I have my new site up and running, I will be working with Michael to publish the changes and maintain EverHarvest's working status.

At the moment I am unable to field support requests except via my email inbox, which you can reach by following the Contact Us link at the top of the site.

Know that Michael made a decision he felt necessary to protect his business, and that he's not 'screwing me' or anything like that. He feels that my inability to provide timely updates to EverHarvest impacted negatively on his business (by virtue of association), and he has taken steps to mitigate any damage to his business's reputation it might cause.

As far as the money goes - Michael and I did share some of the revenue for EverHarvest at one point, but that was part of a deal regarding hosting and support (which he ended up paying back to me at the time anyway). He has provided the hosting of EverHarvest for free for longer than a year (if memory serves). I wrote the Autocrat framework upon which both EverHarvest and EverCraft are built, and he paid me for my time and effort.

Summary: it is my intention to build a new site for hosting EverHarvest. Michael is going to host the authentication server temporariliy while I get the new site up and running. During this time period, there will be no need to purchase license extensions for EverHarvest - your software will continue to work regardless of how much time is left on it. After the new site is up and running, your licenses will be back to normal (and I'll be applying some heavy license extensions as well to cover the last couple of downtimes, plus the time spent in this "limbo" between sites). Michael and I are communicating amicably, and are going in fact considering setting up a sort of 'partnership' whereby we recommend each other's services. There aren't any details on this yet but expect to see something on my new site (still unnamed) within the next couple of weeks.

PLEASE don't go on his forums and try to defend me, ESPECIALLY if your defense includes personal attacks on Michael or his business. That sort of thing will not be condoned by either of us - and while I appreciate the loyalty, it's entirely misdirected.

Wednesday, November 25, 2009

I'm back. =)

Well it's been a stressful several months, but I want to return to blogging.

In case anyone has been curious as to where I've been, here's the scoop. I am no longer living in Seattle WA, and have moved back home to Charleston SC. I lost the job in Seattle, and my family used that event to trigger the move. Apparently it's been coming for a while - everyone (myself included) was homesick. What followed was a week-long cross-country drive from Seattle to Charleston, during which we towed every earthly possession we could fit into our SUV and a UHaul trailer attacked to the back, along with our two kids, roommate, and a cat. If I have one life experience that I'd like to recommend to everyone, it's that - driving across the country.

After arriving back home, we ended up living at my father in law's house, in the upstairs guest apartment, and have been there since. Last month, he told us that we had to leave by the middle of November - hence my post earlier about needing a job in a month or we'd be homeless. I was fighting a bit of angst when I wrote that, so perhaps things weren't as dire as that (happy Ta?) - but it was getting bad.

But three weeks ago I started a new job - almost 4 months after we returned home. The economy sucks - but I'm glad I held out. I'm working for a large multi-national contracting company that builds *things* for our country's and our ally's militaries. I'm working primarily as a .NET developer, but so far I've been called upon to work with VBScript, VBA, JavaScript, and others, in addition to .NET. So far it's been a blast - I love the people, the diversity of work, and the general atmosphere. I will admit that they've got me a bit on the cheap - this is technically an entry-level position - but I don't mind at all. It pays the bills well, and affords me the opportunity to show that I'm worth a lot more than they're expecting, and so far, so good. :)

I have to be a bit careful with what I reveal on the blog - which is why I'm not naming my place of business, nor will I be talking about specific projects. I'll still talk about MacroCrafter stuff as the opportunity presents - I'm still doing updates, planning new software, etc.

A lot of what I'll be talking about soon will be process-oriented stuff. The team I'm on (which consists of 7 developers and 2 analysts) is largely made up of lone coders looking to build their team experience (which is exactly what I'm here for as well). I think we're going to be creating our own process based on Agile, which makes me happy as it's something I've been wanting the opportunity to get into for a while. One of the major perks of this situation is that I will be in on the ground floor helping to build these processes. I'll write more about this later as developments occur.

Tuesday, September 15, 2009

Hunter bot, simplified.

Everyone, thank Tasha (my wife). She said something to me the other day that really got me going on the hunter bot, and actually inspired me to write some real code. She said, "Just write it."

I've been spending so much time thinking about the hithertoo's and whyfor's about it that I haven't touched a single line of relevant code. My biggest problem is and has always been a combination of over-thinking and over-planning. Many of my project concepts are huge ideas - my web game that'll never be built is a prime example of this. It's so large that it would require a team of people as dedicated to it as I am in order to actually happen, but that's a pipe dream.

So in following Tasha's advice, I've managed to get a very simple prototype hunter bot working. To do this, I've opted for a far simpler strategy: instead of following a walkpath, the user selects a 'camp spot', and the system brings viable targets to the camp spot to kill them.

I decided to do this for one primary reason: it'll help me get something out the door. Features can always be added later - with the Workflow system I wrote for Autocrat, this is easy as pie, once I've figured out the logic. But for now, I'd like to get something out to everyone whose waited so long for it - and the camp-bot is it. I'll have a beta version available very soon.

Wednesday, September 9, 2009

Lol

Got my first comment spam today! Somebody (more likely a spambot) posted links to EQ2 plat buying sites on my post regarding running EH in a VM.

I wasn't aware my blog was popular enough to get the attention of spam bots... That's sort of flattering, in a weird and annoying way. =)

Thursday, September 3, 2009

Running EverQuest and ShadowTeq software in a Virtual Machine

Running EverQuest and ShadowTeq software in a Virtual Machine


Required Software:

* - VMWare is not free, and costs $189 for a single license, though there is a 30-day trial. Please note that I do not promote software piracy.


Introduction:

Described in this document is the method by which you can set up and run EverQuest 2 and ShadowTeq software inside a Virtual Machine. There are several reasons why you might wish to do this. First, if you are running an operating system which ShadowTeq does not support (such as Linux, MacOS, or future versions of Windows), you can run a virtual machine (VM) that runs a supported operating system, such as Windows XP, in order to run our software. Second, running inside a VM means you can use the rest of your computer while our software is running, rather than being locked into keeping the EverQuest 2 window always-on-top.

This process is fairly straightforward, if advanced. None of the steps below requires altering your current installation in any way, except for installing VMWare Workstation. Still, if you are not at least comfortable following a set of advanced instructions, I suggest finding someone who will be willing to help you through this. The good news however is that once your virtual machine is up and running, any changes you make to it do not in any way impact your existing system - so you can feel free to experiment inside the VM as much as you like.

This guide assumes you are using exactly the software outlined above in the Required Software section. Some of these (VMWare Workstation, Windows XP) can be replaced with higher versions, although this may change the steps. Please do not deviate unless you already know what you're doing. ShadowTeq won't be officially providing support for this, but I (Erik) don't mind helping out as much as I can - but if you deviate too far from this set of steps, I may not be capable of helping.


Step 1: Install VMWare Workstation 6.5.3:

After you've obtained a copy of VMWare Workstation, you'll need to install it. Double-click on the installation file to begin the installation process. This is straightforward - there aren't any important options to select, so choose Typical installation.


Step 2: Create a Windows XP Virtual Machine:

Now that VMWare is installed, it's time to create the Windows XP Virtual Machine. I'm using Windows XP Service Pack 2, but SP3 is also confirmed to work as well. To do this, you'll need to have either a physical XP CD in your CD-ROM drive, or have an ISO image of the XP CD you intend to use. When you're prepared, launch VMWare, and go to the File menu, select New, and select Virtual Machine. In the window that appears, select the Custom option and click Next. In the next page, ensure that the Hardware Compatability selection is set to 'Workstation 6.5', then click Next.

The next page allows you to choose where to install XP from. If you have a physical CD in your drive, select the first option button, then click Next. If you have an ISO image of the CD, select the second option button, click the Browse button to tell VMWare where your ISO file is, then click Next. The next page will ask you for your XP CD key, your full name, and an Administrator password. Fill in these details and click Next. The next page will give you an opportunity to name your Virtual Machine. I just left mine as the default, but you're free to use whatever name you wish. Additionally you can change where the Virtual Machine files are stored. By default, there's a 'Virtual Machines' folder in your 'Documents' folder that VMs get stored in. When you're done here, click Next.

The next page that appears will ask you how many processors to expose to the VM. If you have more than one processor available in your machine, choose Two. Click Next. The next page allows you to specify the maximum amount of physical RAM that the VM will be allowed to allocate. Note that this means the VM will consume AT MOST this amount, but probably less. I recommend 1024mb. After setting your desired maximum RAM, click Next. The next page allows you to determine the type of network connection the VM will have. I recommend leaving it at the default of 'Use network address translation (NAT)' as this will simplify configuration later on. Click Next. The next page is for SCSI configuration - nothing needs to change here; click Next.

The next page allows you to configure a hard drive for your VM. In our case, we want to create a new virtual disk, so leave it at the default and click Next. The next page allows you to select the type of virtual drive; this selection is largely unimportant, so choose the default and click Next. The next page allows you to set the maximum size of the virtual disk. I recommend 24gb for everything that will need to be installed, but you can choose more if you like. The other options on this page are fine at their defaults, so after you set the size, click Next. Click Next again to select the default name for the disk.

Now we've come to the end of the Virtual Machine creation; click Finish to have VMWare finalize your choices, power up your machine, and install Windows XP. This process is completely automated (if you've followed the instructions) and, when finished, will leave you at the Windows XP login prompt. To log in, type the Administrator password that you specified earlier in the password box.

If all's gone well, you should be greeted with a Windows XP desktop, and the Windows XP login sound effect. One of the first things you should do here is to increase the screen resolution. Currently it's set to 800x600 - much too small to be useful. To change it, right-click on your desktop and select 'Properties,' then select the Settings tab. Drag the 'Screen Resolution' slider until the resolution is at least 1024x768 - any less than that and the EverHarvest or Golem windows will overlap the game window by far too much.


Step 3: Install Supporting Software:

Now it's time to start installing software in your Virtual Machine. Assuming you've used XP SP2, you'll need to install DirectX 9.0c, Windows Installer 3.1, and the .NET Framework 3.5. You'll find links to these downloads at the top of this document. From inside your Virtual Machine, download the files, then install them in the order listed above. Remember, install them inside your Virtual Machine, not on your physical system! All the default installation options are fine for this software.


Step 4: Install EverQuest 2:

Finally, we can install EverQuest 2. Use the download link at the top of this document to download the EQ2 launcher (again, from inside your VM). Unzip it, then run it, and it'll install the base files necessary for downloading and patching EQ2. You should know the drill here - log in to your Station account, and let the patcher run... This will probably take several hours, but you can do other things while you wait.


Step 5: Install ShadowTeq Software:

Now it's time to get our software running. Using the download links on our home page, download the software you're interested in (again, while inside the VM), and install it according to the usual instructions.
... That's it. Really. =)


Step 6: Run:

This works the same as it does on your physical computer - run the application you're interested in running, and log in. Note that you will probably get a 'No Licenses Found' error - that's okay. Just follow the instructions found on this page and you'll be good to go. Configure the software as usual, and run it as usual - the only difference is that you're running it inside the VM.

Now here's the slick part - the culmination of all your efforts. Once the software is up and running, press Control + Alt - and your mouse will detach from the VM's mouse, and you can minimize VMWare, or tab away from it, or whatever - do anything else you want on your computer. If your system is beefy enough, you can even run another instance of EQ2 on your physical computer - or, even, in another Virtual Machine. Theoretically you can have as many VMs running at once as you want - the only limits of course are CPU power, available RAM, hard disk space, and networking bandwidth.


Step 7: Shutting Down:

Shutting down a Virtual Machine works the same way as shutting down a real computer - go to Start and select Turn Off Computer, then Turn Off. The system will perform its shut-down routine, then turn itself off. To turn the 'computer' back on again, select the VM in the left-most list and press the green 'Start' button in the toolbar on top of the window.


That's it!

No, really, that's it. Now that you've got the hang of this, feel free to experiment around. It's really hard to mess this up - and even when you do, you're just dealing with virtual machines - just reformat it if you do something unrecoverable. For more advanced uses of the VMWare software, you might want to consult their documentation, available from the VMWare website.

Enjoy, and good luck!

Wednesday, September 2, 2009

Late birthday present

One of our users has managed to get EQ2, EverHarvest, and EverCraft working in a VMWare Virtual Machine, and has shared the instructions on how to get it working with me!

Why is this such a great birthday present? Virtual Machines are like full computers running inside your physical computer - which means it gets its own (virtual) keyboard and its own (virtual) mouse. While EverHarvest and EverCraft still require EQ2 to be the topmost window on the computer, this can be true inside the Virtual Machine instance while NOT being true on your physical computer!

This means that you can DO OTHER THINGS on your computer while you run our software! Finally! =P

I'm working on getting the instructions in a more user-friendly form before posting them - which should come in the next day or so. Just wanted to post this to get the pot stirring, so to speak... =)

Monday, August 24, 2009

=)

Happy birthday to me,
Happy birthday to me,
Happy birthday dear... meeeee...
Happy birthday to me!

...

I need a life... Lol

Thursday, August 20, 2009

Lambdas and Anonymous Delegates pt 2

So I did exactly what I suggested to myself, and sent an email to Eric Lippert regarding the inline lambda and anonymous delegate business I blogged about earlier today. He's quick - here's his reply:

Ah, good question.

You can make this work by casting to a delegate type.

((Func<bool>)()=>M()).Invoke();
((Func<bool>)(delegate (){return M();}).Invoke();

For lambdas, we don't know whether the lambda is to be converted to a delegate or an expression tree. Since an expression tree cannot be invoked, we cannot allow you to invoke it before we know what you intend.

For anonymous methods, yeah, I suppose we could have designed C# 2.0 to allow invoking them directly. But what would the point be? Why say (delegate(){return M();}).Invoke()" when you could just say "M()"? I agree that for reasons of generality and consistency it would be nice to have, but I don't think disallowing this actually disables many scenarios.


He's right - it's not like this is some sort of necessary functionality. On the one hand, it's great that I can get exactly this functionality by casting to a delegate type first, but on the other hand it's extra cruft. All the same, if some inspired or courageous EverDroid user needs this sort of functionality, it's there.

Thanks, Eric! =)

Inline execution of a lambda expression or anonymous delegate

I had an idea I wanted to try to exploit that would make my VB.NET expression a bit more, well, expressive.

The way I built my expression builder, essentially you pass in a valid VB.NET expression and the expression builder sticks it onto the end of a Return statement inside a static method of a new class, which it then compiles with the stock VB.NET code compiler. Then I use reflection to dig out the compiled method and returns a Func<bool> that invokes the method, returning the result.

This works great for its intended purpose, but it unfortunately restricts my expressions to being, well, expressions. Boolean expressions. Which means they can't do a whole lot of processing, or whatever. That's okay - I don't really *need* all that much. But I enjoy a challenge, and I thought to myself 'Self, why don't we try to use an inline lambda!'

Great idea - except you can't INVOKE a lambda inline. Example:

bool x = ( () => true ).Invoke();

Doesn't work. Operator '.' cannot be applied to operand of type 'lambda expression'. 'Fine,' says I, 'I'll use an anonymous delegate!'

bool x = ( delegate { return true; } ).Invoke();

Operator '.' cannot be applied to operand of type 'anonymous delegate'. Argh. So as far as i'm aware, this is impossible, probably by design. I'll have to ask Eric Lippert about it, since he's been doing his C# design rationale posts lately.

Progress thus far

Truth be told, at this point, progress is slow going. I've been doing a lot of work for my friend Brian, and as it pays more immediately than Macrocrafter work I have to focus on that. It's been calming down of late (unfortunately) so that should afford me more time to work on this stuff.

I've been slowly organizing the work I need to do on this system. So far I've divided it up into several main components that I'll need to build before I can start stitching them together.

Also I've decided to skip the intermediate step and just make a damned hunter bot out of this, so I'll also need to integrate targeting and walking into the system.

Anyway - one of those systems includes a VB.NET compiler, as I mentioned before. All I need to do with this is to take my proof of concept code and make a proper system out of it - something reusable. I'm going to add it to Autocrat. I'll also need a timer that can produce timing events in 150ms intervals - that's the interval at which I'm going to have the system pull down updated EQ2 data. Any of the .NET timers should be capable of doing this so I'm not too worried here. I'm also going to need a state machine engine that can be configured via XML - this will be responsible for persisting the user-editable 'scripts' that will make up the brains of the bot itself. I've got a schema all figured up; all that remains is actually putting the work into it - and then I get to build a UI on top of it, because the last thing I want to require is for people (or myself) to have to hand-edit XML to get it to work.

Coupled with the timer is going to be a system for describing stateful property changes. Here's the problem: my bot engine is going to be evaluating event trigger expressions every 150ms. The expressions are boolean, so they'll be testing data based on the content of the current tick's EQ2 properties. If an expression looks similar to: "Return EQ2.GroupMember(2).Health < 50" - then when group member 2's health drops below 50%, it will trigger the event. This is desired - BUT it will ALSO trigger once every 150ms tick until group member 2's health rises to or above 50. This is NOT desired, so I need a way to expose the concept of state changes: for example, I'd like to rewrite the same expression as: "Return EQ2.GroupMember(2).Health.DroppedBelow(50)". That would return True if, and only if, the previous tick's Health was at or above 50 AND the current tick's Health is below 50.

So I'll need to figure out an efficient system of encapsulating old state and exposing it via these state descriptors. I'm sure I'll figure it out.

But you can see why I've been making slow progress here. =) In between kids, contract work, looking for full-time work, EQ2 updates, and other life, I don't have much time for experimentation, which is a shame.

Saturday, August 1, 2009

Happy Birthday baby girl =) And some other stuff.

So my daughter just turned 2 years old today. We had a party at CiCi's, and fun, pizza, and cake was had all around. =)

A friend of mine in NYC has a lot of extra work he's unable to do himself, due to having his own full-time job, family, etc., so he's farming it out to me. It's a great situation as I currently have a work deficit, so taking it off his hands helps me out a lot. So far I've updated three websites owned by the same company - took me the better part of a day to get it all completed, but it wasn't terribly hard. Mostly grunt-work, but it pays, and it's not brainless. I am by no means complaining. =)

Finding work in Charleston, SC has been difficult - the two large development companies out here have both rejected me as being "not quite what they want" - I don't have any team-oriented experience, or large enterprise experience, which is all they're looking for out here. My argument is that if everyone wants to hire people with prior team experience, how can anyone who doesn't have it get it? Eventually there'll be nobody left except people *without* team experience, and then what will they do?

Bah. Perhaps I'm bitter - I need a job so I can put food on the table and pay rent and all that rot. It's frustrating. I'm actually hoping I find a computer / network tech job I can do, rather than programming - I think I'll have more fun doing that, since I'll get to work with people, help solve their immediate problems, etc.

Maybe I'll see if I can find investors for that computer recycling business I've been thinking of starting.

Anyway - very little work has occurred on my next EQ2 project, which one of my friends has dubbed EverDroid - a name I think I'll use. I need to build an Eval system into Autocrat, because this is something I'm going to use a lot in projects to come, for the sake of configuration and behavior customization. That won't be hard - I've got a simple console proof of concept working just fine, compiling expressions in VB.NET (which I think non-programmers will find easier to reason about - Microsoft agrees, and has done the same thing for their expression compiler in Windows Workflow 4).

EverHarvest had a good month last month - decent sales, despite the economic issues. Not nearly what it used to be, but then again I never expected it to be. Most people seem to be happy with it, when it works - which it's not at the moment; I've been working on the next update in response to Sony's latest changes, but they're doing their rapid-fire patching again, which always makes me want to wait... I was half-way through the last set of updates when they patched again yesterday, ruining my work. Ah well - such is the price to pay. Overall it's nothing to complain about - I work on it maybe two days total out of every month.

So, that's my update today. I'll get back to the millstone again and crank out the EH update. I really need to write some helper tools for this thing...

Saturday, July 18, 2009

So far, so good.

Early proofs of concept indicate this might be a viable option. Here are some of the hurdles ahead of me:

Trigger condition evaluation: I'm planning on using VB.NET as the language for trigger condition expressions. I've built a simple test that takes an arbitrary boolean expression, compiles it via CodeDOM into an in-memory assembly, and returns a delegate to invoke it with all the necessary information that will be required of the bot. This works well so far, but of course it remains to be seen how well it'll work in practice. I may change this to having the expression compiled into a System.Linq.Expression, which I could then compile into a delegate - I think that would be faster than the CodeDOM method I'm using now. Profiling will tell.

Dynamic state machines: Part of the system will be handling different states. I'm using states as a logical grouping of events for a common scenario. For example, a Fighter bot could have many states that it could be in at any one time; an out of combat state, an in-combat state, a dead state, and so on. Each of these states can have their own grouping of events, possibly having actions that force the machine to transition between states. I have some experience with state machines so this shouldn't be too much of a challenge.

Ability mapping and timing: Another vital part of the system is my Ability Mapping concept. Instead of having each user modify their scripts to include their character's own personal spells and combat arts, scripts will instead reference ability mappings. These mappings are then configured by the user to refer to one or more in-game abilities, each of which has its own cast, reuse, and duration timers. When a script action invokes the mapping, the system will use the first ability it's able to, according to its position in the mapping (top to bottom) and the status of its timers. This way, said Fighter bot can have a mapping called 'attack' that its user could have configured with all his character's single-target combat arts, so that every time that 'attack' mapping is invoked, one of those combat arts is used. I'm still conceptualizing this particular feature so any more detail would be speculation / brainstorming, which I will save for another post.

Configuration and UI: Of course, all of this complexity needs to be presented as simply as possible. I do not intend for people to manually edit XML in order to change these scripts, so I'll be building a script editing UI for that purpose. In addition, the UI will need to include a mapping editor, as well as a place for entering script-declared variables. All of these things will need to be data-aware, and some of them dynamically created. I've been debating with myself whether I want to use XAML and WPF for the UI, and while this sounds like it might be a good use of WPF, I still haven't taken the time to crest the learning wall, and with my current job situation I don't know if I want to take that time now.

There's more, but this is getting long already - I'll post again either tomorrow or the next day with more.