• entries
23
28
• views
20266

## Getting Back In The Game...

Heyo! Been forever and a day, but I'm back, and hopefully to stay. And be productive, because like most others here, I've a game idea I want to see come to fruition. As such, I've disconnected WoW and Guild Wars and other non-productive distractions, trying to get down to business. Part of getting down to business for me is 'accountability', which will likely be taking the form in at-least-weekly journal updates. For now I'll be using this /old/ journal, but if my game starts to see progress and take off, it will get its own separate journal. For now, the game's ideas and concepts shall remain hidden in mysterious shadowy shadows.

In the past week or so, in my spare time between whatnot, I've been researching what I'll need to be using to get the job done. It's a bit tricky since I've not done graphical game development in awhile, though I have been productive for a MUD of late, so I'm not really inexperienced, per se; however, I tend to like to reinvent the wheel, depending on the wheel, and learn best by failing. We'll see how this plays out. For now, the technologies and other stuff I've been looking at and thoughts regarding them (this is where I'd greatly appreciate feedback/criticism, for those so inclined):

# C#/Mono - Language (client/server/everything)

Hopefully sidestepping Holy Wars and whatnot, I have some experience and memories of C# a few years ago, fond memories all. My language experience of late has largely been VBA, custom scripting language for the aforementioned MUD, and a bit of Java/Javascript/HTML/CSS. I'm more familiar with some of these, and other languages, but it has been a good while and I recall only more concepts than anything language specific, really. Regardless, my previous C# experience was all .NET, but as I would like for my game to be more cross-platform inclined, I've been looking at Mono and it seems to fit the bill, though I've yet to test how difficult it is to target to other platforms, just what I've seen on the web.

# Awesomium - GUI

So one of the areas which I'd rather not reinvent the wheel too much if I can help it is the area of GUI. I had attempted some time ago to make a little coder control, and may end up picking that up again for all I know, but I realized that I got too caught up in the nuances and didn't make it very far. I honestly don't remember how far I made it, but I did learn a bunch of neat stuff, which I've since forgotten. Anyway, Awesomium looks to be a neat little HTML UI Engine for .Net/Mono. While I'm not sure of how badly this will effect performance, etc., I do like the idea of using HTML/CSS/javascript for GUIs in a game. Saves me a lot of trouble, and it can use existing technologies. I had looked at other such things, notably Chromium/Blink/etc, but they seemed...not as ready out of the box as I'd like at the moment, though I might end up using them in the future. Awesomium is free "for teams with <$100k revenue", so I should be good for a long while. # Google Cloud or Amazon Cloud - Servers/Databases So my game idea certainly isn't a dreaded MMO idea (I recall comics about marrying the Hulk which were post here, some time ago), but it does require servers and databases. I know that I'd like for it to scale, both in case it does take off and in case it doesn't, the latter so I don't end up wasting money for unused resourced. I'm currently torn between Google Cloud and Amazon's Cloud, partly due to server ignorance since I've little to no experience with such things (I plan on starting out simple with the game, using it as a conduit to learning). I am somewhat of a Google fanboi, so I'm inclined to lean towards them, especially since I can just go all Google and use their APIs to handle any future purchasing abilities or to login, instead of having a separate username/password/whatever just to track and play. On the other hand, Amazon's seems to be more popular, and I honestly don't know if this is just a service thing or if Google's has yet to catch on. Another thing I guess I dread is setting all of this up for Google's only to have it be faded out like Google Wave and other such technologies. # SDL/OpenGL - Graphics So this is where part of my reinventing the wheel issue comes in. I'm not so bad where I want to go all hardcore and use nitty gritty hardware calls, but I do want to write my own engine for handling things, partly because that's where I get my enjoyment. I will be open and say I've little 3D graphics experience, having written nothing more than a few tech demos almost, gosh, a decade ago (so old...). As with the server, I plan on starting out small and slowly implementing more of the custom engine using SDL/OpenGL over time. It will likely require occasional rewrite of the engine/code, but I honestly feel that code, or at least parts of it, should be rewritten entirely if new features and such have been slapped on over time. So there you have it, at least one item I'm still not sure on, and all of them I'd love input before I get cracking. I realize there will likely be (quite) a few responses about starting out small on server/3D graphics stuff, but I'd like to at least try to learn as I go with the game, and failing that perhaps step back and write smaller demos working my way up. (I'm quite likely to sandbox newly learned stuff anyway, in small small demos, but then just slap that in the main game and rewrite it after it has a good bit slapped together). Thanks for reading, and Cheers! ## Crisis of Faith? Right-o. This will be my last post on here for about a year. Or it should be if all goes well. As you may have known prior (or just after reading the bit at the top of the journal), I'll be heading off to the Air Force in February. ~95 days left till I ship from the day of this post, give or take a day. As for my crisis of faith? Well, get ready for a n00bish excuse story. :| I'd been dabbling in programming since I was 10. A couple years were on and off at the start of it. For various reasons, mostly my lack of discipline/willpower and just being easily distracted in general, I've never made anything worth mentioning. Ever. I've dabbled plenty in various areas. I've independently researched a handful of chipsets and early consoles. Read plenty of articles over the years on various aspects of programming and gamedev. I just don't seem able to *do* it. Like my code editor project, for instance. I've made plenty of progress on it two or three times, but I always end up rewriting it for some asinine reason. Or I'm torn between whether I should make it for WinForms? What about WPF? Silverlight? AIR? :| Once I thought it would be helpful if I dropped dabbling in programming so I'd miss it, but I never did. I mean, I could go a week or two and all I'd do was read an article or mess with some code in Visual Studio that didn't accomplish jack squat. Don't get me wrong, I still have a "burning desire", if you will, to program/code/develop. But I just don't seem to appreciate it or something. *shrug* Anyway, I figure the 8 months between Basic Training and Tech School that I'll have away from computers/internets, both AF imposed at the start and probably self imposed at the end, will help, but an extra 3 months or so aren't going to hurt. So, as a test of my "crisis of faith" in programming, I figured I'll just drop pretty much everything. No coding. No article reading. Nothing. The most I'll do is maybe actually learn some decent maths, from calculus and onward. If after about a year (which it will be from now, if you include the ~30 days I get to spend home after Basic/Tech), I'm still interested, perhaps I'll appreciate it more. Besides, the discipline that BT will give me will likely help. And if I'm not still interested in programming...well, I dunno. I don't really see me not being interested in programming, but I suppose I could find some other hobby/activity to take up. It isn't really likely though. So perhaps my "test" isn't so much to test my desire to program, but rather to increase it? I dunno. So anywho, you guys take care. After a day or so to check up on comments, I probably won't visit GameDev for a year. So don't forget me when I come back. XD ## Livin' on the Wave [Edit: Per the request of benryves, the apparent resident grammar expert, invite should not be used when invitation is available for usage. So I've changed it.] Huzzah! Thanks to dohtem giving me an inviteinvitation, I've been fortunate enough to play around with Google Wave for the past...almost a week, I think. I've completely bitten the hype and I think it is super crazy awesome, etc. So much have I bitten the hype that I'm going to have a go at "living off the Wave" in so far as a site/blog(wlog? wavlog? ???) goes, aside from this journal. So now it is just a countdown until some domain sitter grabs my old one up. Hope it isn't some pron site. [disturbed] So far as any of my projects go, nothing. Nada. Zip. Zero. Zilch. No progress. :| I really need to get some progress done. It isn't like I have a viable excuse such as a job, which I also need to get. Maybe. Only four months till I leave for Basic Training. Maybe there will be something to report next time. Maybe. FOUR MORE MONTHS! D: [EDIT] ------------------------------------------------------------------------------- Also, I've been playing around with the Google Wave gadgets thingy, only made one to display your XBox GamerCard. :| Any ideas would be appreciated. ## Of rnfnCodeLite and Grammars, Part 2 Mirrored Here What? Part 2 already? ZOMG! SRS BIZNIZ TIEM! Anywho... Righty-o. So in my previous post, I went over the rough draft of the rnfnBNF language. And now I'm supposed to go over "Intellisense, Scope, and AutoFormatting ideas/problems I have, as well as any changes I come up with and/or from feedback." Well there hasn't been any feedback at the time of this writing, so that bit is out the window. And I haven't come up with any changes overnight in my sleep. So this leaves us with my ideas/problems regarding IntelliSense, Scope, and AutoFormatting. ## Scope Scope is a bit problematic, at least I think it might be. I'm presuming/hoping scope only ever works in levels, with the innermost/lowest level being the one with the most access. If I presume this, then I can just deal with having _startScope() and _endScope(). This, at least, allows for a kind of "general" scope. I'm still thinking as to whether or not there is any benefit/disadvantage to having the scopes be named, for IntelliSense purposes. ## IntelliSense My ideas for handling IntelliSense still have a few holes. The first of which is handling scope, etc. Which is to say, while I may know every function in class FooBar of namespace Foo.Bar, I don't want the IntelliSense listing them as Foo.Bar.FooBar.classname in the suggestion modal. Rather, I need some form of scope division, which'll probably just be taken care of by assigning a scope seperator(s). Also, for something like using System.Windows.Forms, I need something in place to handle this "prefix" bit, though I suppose in conjunction with the scope seperator(s), I could have _addScopePrefix("System.Windows.Forms"). Of course, I need some manner of getting the unknown bit into it. That is to say, if the rule were using="using ", namespace, terminating-symbol;, for example, I'd need to get namespace in _addScopePrefix(...) somehow. At the moment, I'm debating between yet another function, such as _setParse(variable:rnfnBNF grammar), or something like variable:rnfnBNF grammar. So the difference would be between using="using ",_setParse(_namespace,namespace) _addScopePrefix(_namespace),terminating-symbol; and using="using ",_namespace:namespace _addScopePrefix(_namespace),terminating-symbol;. Personally, I'm liking the latter example at the moment. Another problem with IntelliSense is building a "base" to work off of. For example, having the IntelliSense data for the .NET platform in a usable format for multiple languages. Or maybe I'll just let the program using the control provide this information. That'd probably be easiest/best. I still have to consider whether I want to allow for multi-language intellisense. >_> ## AutoFormatting Off the top of my head, the things that'd fall in this category mostly involve the placement of tabs, spaces, and/or newlines, the first two usually in regards to the level of scope that they take place. Something like _Scope()*'\t' would insert N tabs where N is the scope(or indention) level. As for actually making it part of AutoFormatting, and not just part of the rule definition, probably have something along the lines of _AutoFormat(rnfnBNF grammar), which would insert the rnfnBNF grammar if, and only if, AutoFormatting is turned on. Might throw in _AutoFormat(option=value:rnfnBNF grammar) to handle AutoFormatting options. Of course, I've have to come up with a safe way to generate a result for the rnfnBNF grammar, in case someone gets all funky with ORs and Optionals. I'll likely just take the first (left-most) of the ORs, disclude the optionals, etc. Will there be a Part 3? Who knows... ## Of rnfnCodeLite and Grammars, Part 1 Mirrored Here Right, so in an effort to design a decent parser for rnfnCodeLite to use for syntax highlighting, as well as possibly IntelliSense and AutoFormatting, I need to write out what I need for it to do, and throw out some rudimentary ideas. For whatever reason, doing so in WordPress' tool seems somehow better than plain ol' notepad(or the plain text editor in VS, or any notepad clones). Plus, if I throw this in my GameDev Journal, where someone might actually read it, I might get some decent feedback. ## rnfnBNF Specs I was originally writing out what the rnfnBNF grammar, as I'm calling it, would need to do, and then I was going to specify the features after. However, this came off as confusing, or at least the way I was going about it. So instead, I'll list my idea of what the specs will be like, though they are certainly not set in stone. ### EBNFesque Since rnfnBNF is based somewhat off of EBNF, it will follow most, if not all, of the same rules(as seen on the wikipedia page): Firstly, defining. Unlike EBNF, where it is just =;, rnfnBNF should also allow for the setting of variables/options. As it stands, I'll likely just use rule=definition; for rules,$variable=value; for global variables, and %option[type]=default-value;. Should [type] not be a recognizable value for rnfnBNF options(such as a boolean, Color, string, etc.), the option will be ignored. The main difference between the global variables and the options is that the options would be saved between instances of the rnfnCodeLite control, so such things as color preference could be altered in an Options/Preferences form of the control and used when the rnfnBNF spec file is used again. Global variables could either be used solely by the spec file, or if there is an underscore between the \$ and the name of the variable, it would indicate a special variable used by rnfnCodeLite, such as the language(s) the rules are intended for, default color, etc. (Note: This probably won't have much bearing right now, but variables will be treated as references.)

For both rules and variables, the rest of the EBNF grammar would hold. (*...*) for comments, ?...? for special sequences, etc. I might consider making the concatenation symbol optional for easier reading, but possibly not. Fortunately, EBNF allows for two methods of extending it even further:

### EBNF Functions

Since there is a concatenation symbol, something like foobar (whatsit) isn't considered legal, which allows for special functions to be thrown in. Should I make the concatenation symbol optional, I'll likely be making the parser check to see if foobar(whatsit) was one such function that it had. If so, it'd parse as a function, if not it'd be treated as a regular foobar,(whatsit).

Since "," is already in use, and I might want to allow for rnfnBNF grammar to be used as an argument inside a function without tedious quotation marks, I'll likely use another character for argument seperation. For now, I'll use the ":" character, but that isn't concrete.

A few functions I'm toying around with having included are:

• _if(variable=value:rnbnBNF grammar)

• _elseif(variable=value:rnbnBNF grammar)

• _else(rnbnBNF grammar)

• _ifexists(variable:rnfnBNF grammar)

• _create(variable:value)

• _delete(variable)

• _regexp(.NET regexp pattern)(iffy)

• functions in respect to scope/level

• functions in respect to intellisense

• functions in respect to autoformatting

### EBNF Special Sequence

Normally, the ?...? sequence seems to be meant for including characters or somesuch that aren't easily accessible by the keyboard, etc. Such as ?PI? might stand for the UTF representation of pi(that I'm too lazy to look up right now). However, rnfnBNF will use it not as an extender of the grammar, but as an extender of the rule. This is to say, anything in ?...? isn't part of the definition of the rule, but something that pertains to the rule in itself. This could include details to the Intellisense to track any instances of this rule in the language(such as declaring a function), setting options specific to this rule(color/back color of a number), etc.

### Context-Free Free?

Not having researched context grammars very much, but looking at the Definite clause grammar, it seems that allowing a rule to have arguments, it can allow for context-sensitive grammars. I'm leaning towards implementing this right now, but if I do I might make paramter/local variables to a rule be preceded by a special character, maybe "_"? rule(_foobar)=something | _if(_foobar="yay":somethingAdditional); doesn't look too terribly bad. Plus, you can know if a variable is local or not just by looking.

## Part 1, Fin

It is getting late, and I've been writing and rewriting this post for awhile now. I'll leave it as it is for the most part. Might make some minor changes if I notice 'em, but anything else will have to wait for Part 2. Hope the writing isn't too "splotchy", as I jumped around quite a bit.

Part 2 will likely cover Intellisense, Scope, and AutoFormatting ideas/problems I have, as well as any changes I come up with and/or from feedback. At this rate, however, this grammar is getting incredibly complex. I'll have to look at it and see if I can't implement it in a fashion where it is easy/simple, but not take up too much room. I'm toying with treating variables and rules all as one element, at the moment. This would mean I could handle them the same. This would also mean that variables could be functions. i.e., foobar and foobar(bleh) could be defined. Or maybe I'll just throw away variables, consider them to be rules, and just have rules and options. I might do that.

Anywho, before I digress any further, thanks for reading, and please leave feedback if you have it on the grammar ideas.

## Closing In

Righty-o! I'm closing in on getting the control finished up. Progress moves a bit faster when one actually works on the project. Granted, I'm only working a little on it, but that is a little more than what I was. Just gotta keep trucking. Etc.

Horizontal scrolling is now implemented in rnfnCodeLite. It has yet to be tested for large quantities of lines, but the tests I performed on a few lines seems to indicate that it is working quite nicely. I'm sure it could be optimized, but it increases/decreases the horizontal scrollbar's maximum value appropriately for now. A few 'weird' bits that I may or may not work on, depending. For example, it takes a few characters before the scrollbar provides any scrolling. This is possibly due to my having it's LargeChange value set to text area's width, which seems a bit large. I think Visual Studio's is using something like 1/5th of the width? Or maybe it is just an arbitrary number. Not sure, but it definately seems to not be the text area's width.

Thinking about toying around with allowing the code editor's contents to be printed via System.Drawing.Printing.PrintDocument, but currently in a bit of a rut regarding GDI and the resolution of the page being printed. If I don't find a nice workaround, I may just ditch it, as it isn't essential, but would be really nice.

The next step I've got to making it a nice little text editor is implementing text selection. I've been toying with various ideas for this in my head, and I'm pretty sure I'm going to settle for multiple selections. This would allow for quick find/replace that I'll also probably be implementing. The only drawback to using it for this would be if the user hit the backspace key, though I suppose a quick CTRL+Z would solve that.

Speaking of CTRL+Z, I also have to implement an Undo/Redo system. Through numerous mental evolutions, I've decided it is going to be selection based. If there is no text selected, it'd operate just like a regular Undo/Redo would. However, if text were selected, it would perform the most recent Undo/Redo(as appropriate) for that text and only in regards the selected text. Previously, it was going to Undo/Redo the entire operation if it had occurred on a line that was in the text selection, but upon explaining this to a friend, he pointed out that it would get a bit confusing. So, if I do go this route (there is always the chance it'll prove not worth the effort), it is likely that only part of the action would be redone/undone. For example, if I'd pasted "foobarbiz" in the middle of "tutu", highlighted "barbiztu", and then hit CTRL+Z, the result would be the text "tufootu" with the next undo action being to remove the "foo" bit. In theory, I don't think it'll be too bad going backwards through the collection to find the appropriate area of text, nor altering the undo/redo action if it is only a partial undo/redo. The problem I'm currently thinking on is whether to allow for infinite undo/redo. I haven't done any testing on it, but surely it isn't going to suffice just storing it all in memory? And I can't really store older parts of it in a file since any performance benefits would be lost with this "partial-selected-text" undo/redo scheme. Hmmm.....

So, yeah. When I get those two done, debugged, and tweaked, all I should have to do is add ContextMenu support and it'll be a nice little text editor. The only other major thing after that, that I can recall, will be to implement a keyword syntax highlighter to go along with the default text 'engine' as two in-package CodeEngine's. Hopefully others'll take an interest and start writing better CodeEngine's, whether they are all encompassing or just for a specific language. For this post's code snippet, I think I'll show what the CodeEngine class is so far, from Reflector's point of view:
public abstract class CodeEngine{    // Fields    internal rnfnCodeLiteData data;    // Methods    public CodeEngine(rnfnCodeLite master);    public virtual bool CanPrint();    public abstract int CaretCharOffset(Graphics graphics, Line line, int caretPixelOffset);    public abstract int CaretPixelOffset(Graphics graphics, Line line, int caretCharOffset);    public abstract void Draw(Graphics graphics, Line line, Rectangle area);    protected int FindAfter(Line line, string query);    protected int FindBefore(Line line, string query);    protected Line GetLine(int linenumber);    protected Line[] GetLines(int lineNumber, int lines);    public virtual void MouseClick(rnfnCodeLite control, MouseEventArgs e);    public virtual void MouseDoubleClick(rnfnCodeLite control, MouseEventArgs e);    public virtual void MouseHover(rnfnCodeLite control, EventArgs e);    public virtual void OnHelpRequested(HelpEventArgs hevent);    private void OnLineChanged(int lineNumber);    public virtual void Print(CodeEnginePrintDocument document, PrintPageEventArgs e);    public virtual void Replacing(ref int startLine, ref int startOffset, ref int length, ref string text);    protected void SetCollapseData(Line line, int linesToSkip);    protected void SetIcon(Line line, Icon icon);    // Properties    protected Color BackColor { get; set; }    protected Font Font { get; set; }    protected Color ForeColor { get; set; }    protected int LineCount { get; }    protected bool ShowCollapseArea { get; set; }    protected bool ShowColoredIndicator { get; set; }    protected bool ShowIconGutter { get; set; }    protected bool ShowLineNumbers { get; set; }    protected TextFormatFlags TextFormatFlags { get; }    // Nested Types    public abstract class CodeEngineData    {        // Methods        protected CodeEngineData();    }    [StructLayout(LayoutKind.Sequential)]    public struct Line    {        internal LinkedListNode line;        internal Line(Text.Line data);        internal Line(LinkedListNode line);        public int CollapseData { get; }        public Icon Icon { get; }        public string Text { get; }        public CodeEngine.CodeEngineData Data { get; set; }    }}

Also, if you're still sticking around and are interested, here is the DefaultText bit, a 'basic' implementation of a CodeEngine that acts as the default engine for the control:
public class DefaultText:CodeEngine{    public DefaultText(rnfnCodeLite master):base(master){}    public override void Draw(Graphics graphics,Line line,Rectangle area)    {        TextRenderer.DrawText(graphics,line.Text,Font,area,ForeColor,TextFormatFlags);    }    public override bool CanPrint()    {        return true;    }    public override int CaretCharOffset(Graphics graphics,CodeEngine.Line line,int caretPixelOffset)    {        //Past the end        if(caretPixelOffset>TextRenderer.MeasureText(graphics,line.Text,Font,new Size(),TextFormatFlags).Width)            return line.Text.Length;        //At the start        if(caretPixelOffset<0)            return 0;                //Iterative Binary Search        int low=0;        int high=line.Text.Length;        int mid=0;        while(low        {            mid=low+(high-low)/2;                        if(TextRenderer.MeasureText(graphics,line.Text.Substring(0,mid),Font,new Size(),TextFormatFlags).Width                low=mid+1;            else                high=mid;        }        int middleDiff=Math.Abs(TextRenderer.MeasureText(graphics,line.Text.Substring(0,mid),Font,new Size(),TextFormatFlags).Width-caretPixelOffset);        int lowerDiff=middleDiff;        try{lowerDiff=Math.Abs(TextRenderer.MeasureText(graphics,line.Text.Substring(0,mid-1),Font,new Size(),TextFormatFlags).Width-caretPixelOffset);}catch(Exception exception){}        int higherDiff=middleDiff;        try{higherDiff=Math.Abs(TextRenderer.MeasureText(graphics,line.Text.Substring(0,mid+1),Font,new Size(),TextFormatFlags).Width-caretPixelOffset);}catch(Exception exception){}                if(lowerDiff            return mid-1;        if(higherDiff            return mid+1;        return mid;    }    public override int CaretPixelOffset(Graphics graphics,Line line,int caretCharOffset)    {        if(caretCharOffset<=line.Text.Length)            return TextRenderer.MeasureText(graphics,line.Text.Substring(0,caretCharOffset),Font,new Size(),TextFormatFlags).Width;        else            return TextRenderer.MeasureText(graphics,line.Text,Font,new Size(),TextFormatFlags).Width;    }    public override void Print(CodeEnginePrintDocument document,PrintPageEventArgs e)    {        if(document["page"]==null)        {            //Haven't done any printing yet.            document["page"]=1;            document["line"]=1;            document["char"]=1;        }    }    public override string ToString()    {        return "Default Text";    }    internal bool ShouldSerializeFont()    {        return !Font.Equals(Control.DefaultFont);    }    public new Font Font    {        get{return base.Font;}        set{base.Font=value;}    }    [DefaultValue(typeof(Color),"ControlLightLight")]    public Color BackgroundColor    {        get{return BackColor;}        set{BackColor=value;}    }    [DefaultValue(typeof(Color),"ControlText")]    public Color TextColor    {        get{return ForeColor;}        set{ForeColor=value;}    }}

I'll likely wait to explain everything properly when I get around to writing the documentation for making one's own CodeEngine, which will be after I write up some Intellisense-type stuff, if I even bother with that. Also, the Print function is a bit lacking since I'm, again, having problems with that.

Please feel free to comment, critique, question, etc.

Mirrored here

[Edit: Fixed my not having swapped pre tags for source]

## .NET Designer Fun

Had a good bit of fun today implementing the Visual Studio Designer end of CodeEngine. Prior to this, the Engine property of my rnfnCodeLite control had been non-interactive in the Designer. Now you can select all known classes that inherit CodeEngine, and aren't abstract. You can also set the properties of the class from the PropertyGrid. Implementing this was annoying as heck at times, but I managed to get it all done in one day, and I'd say that's a fair bit of work, especially considering the lack of it of late. :p

Firstly, the bit about selecting known classes that inherit CodeEngine:
    internal class CodeEngineUITypeEditor:UITypeEditor    {        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)        {            return UITypeEditorEditStyle.DropDown;        }        public override object EditValue(ITypeDescriptorContext context,IServiceProvider provider,object value)        {            if(context!=null&&provider!=null)            {IWindowsFormsEditorService editorService=(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));                if(editorService!=null)                {CodeEngineListBox listBox=new CodeEngineListBox(editorService,context);editorService.DropDownControl(listBox);                    return listBox.SelectedItem;                }            }            return base.EditValue(context,provider,value);        }    }    internal class CodeEngineListBox:ListBox    {IWindowsFormsEditorService editorService=null;        public CodeEngineListBox(IWindowsFormsEditorService service,ITypeDescriptorContext context)        {editorService=service;            Sorted=true;foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())foreach(Type type in assembly.GetTypes())                    if(type.IsSubclassOf(typeof(CodeEngine)))                        Items.Add(Activator.CreateInstance(type,(context.Instance as rnfnCodeLite)));SelectedIndexChanged+=OnSelectedIndexChanged;        }        void OnSelectedIndexChanged(object sender,EventArgs e)        {editorService.CloseDropDown();        }    }

Two bits here. The CodeEngineUITypeEditor bit just tells the property grid that we're a drop-down UITypeEditor(meaning we're to be used "within" the property grid, versus being a dialog window) and what to do when we're being used. The only thing we do is add a CodeEngineListBox, which is our second bit. All this does is extend System.Windows.Forms.ListBox and displays every implementable type that is a subclass of CodeEngine. The only downside, at the moment, is the first time you click it in the Designer, it takes quite a few seconds to go through all the assemblies looking for appropriate types. It gets faster the more you use it(or at least in my quick two-minute testing), but the first time is still a doozy. JPatrick in #gamedev@AfterNET.org was discussing it with me, and I think he said there was a way to get all the types from TypeDescriptor.GetEditor, but I didn't really understand all of it. :x

Right, so apparently what I wanted already existed. Imagine that. :p System.ComponentModel.ExpandableObjectConverter for those of you interested.
Secondly, I wanted to be able to implement any and all properties of any and all classes that inherited CodeEngine. I'm treating any properties visible to the property grid in these classes as being options/settings for the engine. I've already implemented a runtime feature where right-clicking on the 'deadspace' area between the scrollbars pops up a dialog window showing a property grid with the properties for the engine, so everything is all set runtime. I wasn't quite sure how I wanted to do this in the Designer until I took a look at the property grid, and noticed that some properties had sub-properties, such as Font, Size, and Rectangle types. After a bit of research, I found out this was due to having a TypeConvertor, which is implemented here:
internal class CodeEngineConverter:TypeConverter    {        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,object value,Attribute[] attributes)        {            return TypeDescriptor.GetProperties(value).Sort();        }        public override bool GetPropertiesSupported(ITypeDescriptorContext context)        {            return true;        }        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)        {            return context.Instance.GetType().IsSubclassOf(typeof(rnfnCodeLite));        }        public override object CreateInstance(ITypeDescriptorContext context,System.Collections.IDictionary propertyValues)        {            if(propertyValues==null)                throw new ArgumentException("propertyValues");            CodeEngine engine=Activator.CreateInstance((context.Instance as rnfnCodeLite).Engine.GetType(),(context.Instance as rnfnCodeLite)) as CodeEngine;            foreach(PropertyInfo info in engine.GetType().GetProperties())            {                if(propertyValues[info.Name]!=null)                    info.SetValue(engine,propertyValues[info.Name],null);            }            return engine;        }        public override bool CanConvertFrom(ITypeDescriptorContext context,Type sourceType)        {            return((sourceType==typeof(string)||base.CanConvertFrom(context,sourceType))&&context.Instance.GetType().IsSubclassOf(typeof(rnfnCodeLite)));        }        public override object ConvertFrom(ITypeDescriptorContext context,System.Globalization.CultureInfo culture,object value)        {            if(!String.IsNullOrEmpty((string)value)&&context.Instance.GetType().IsSubclassOf(typeof(rnfnCodeLite)))            {                string[] str=(value as string).Trim().Split(culture.TextInfo.ListSeparator[0]);                CodeEngine engine=Activator.CreateInstance((context.Instance as rnfnCodeLite).Engine.GetType(),(context.Instance as rnfnCodeLite)) as CodeEngine;                PropertyInfo[] propertyInfo=engine.GetType().GetProperties();                if(propertyInfo.Length==str.Length)                {                    for(int i=0;i                        propertyInfo.SetValue(engine,TypeDescriptor.GetConverter(propertyInfo).ConvertFromString(context,culture,str),null);                    return engine;                }            }            return base.ConvertFrom(context, culture, value);        }    }

Bleh. Seems like WordPress's Visual editor doesn't like the "