Search This Blog

Tuesday, January 31, 2012

Game Studio design, and code

Since the game studio is the primary interface for game development for the engine, a lot of thought and planning is required to make it as useful as possible.

First, a screen shot:


Now, the nuts and bolts.

The main form has a menu, tab control, and frame.  The frame (on the right side) will hold the project files in a tree view.  All script files will be listed there.  The tab pages will be where project files are edited.  The File menu allows projects to be opened, saved, closed, and printed.  The Edit menu contains standard cut, copy, paste, and select all commands.  There will be more menu items added for different file types.  I'm going to add in code compiling and testing functions soon.

There are different types of tab pages.  The one that is visible is a code editor tab.  All of the UI controls are UI members of one custom UI object, CodeControl.  The HScroll bar, VScroll bar, and Combo box are just regular controls as members of the custom control.  The text and line numbers are being drawn onto a customized group box object.  The custom group box object code is not very complicated, it just modifies some of the functionality of the default group box UI object to make it behave differently. 
The code for the custom group box:

Public Class EnhancedTextBox
    Inherits GroupBox

    Public Event DrawMe(ByRef e As System.Windows.Forms.PaintEventArgs)

    Public Sub New()
        MyBase.New()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True)
        Me.UpdateStyles()
        Me.Cursor = Cursors.IBeam
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Up Or keyData = Keys.Down Or keyData = Keys.Left Or keyData = Keys.Right Then
            OnKeyDown(New KeyEventArgs(keyData))
            ProcessCmdKey = True
        ElseIf keyData = Keys.Tab Then
            OnKeyPress(New KeyPressEventArgs(Chr(9)))
            ProcessCmdKey = True
        ElseIf keyData = Keys.Delete Then
            OnKeyPress(New KeyPressEventArgs(Chr(127)))
            ProcessCmdKey = True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
    End Function

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        e.Graphics.FillRectangle(Brushes.White, Me.ClientRectangle)        'clear client area
        e.Graphics.DrawRectangle(Pens.DarkGray, Me.ClientRectangle)        'draw boarder
        RaiseEvent DrawMe(e)        'call the draw event
    End Sub

End Class

The code for the custom rendering is a part of the CodeControl custom UI object.  I wish I could list all of that code here, but it is about 950 lines of code long.  Also, the code is not complete yet; there is a lot of functionality that I need to write.  When I get more of it done, I want to make a post devoted to covering the ins and out of how it works.
The brief version is the CodeControl uses the KeyPress, KeyDown, MouseDown, MouseMove, and MouseUp events from the EnhancedTextBox object to capture user input, and manipulate text that it stores in an array.  The DrawMe event triggers rendering code on the screen, using values from the HScroll and VScroll to determine what text to draw.  A syntax processor sets the color on recognized keywords, double quote delimited text, and numbers, that the DrawMe event uses to render colorized code.  I created overrides for the Text and Font properties of the EnhancedTextBox to handle getting and setting text from the control, and setting the font to be used for rendering.

More to come later...

Saturday, January 28, 2012

VB.net, Getting arrow key input on controls

If you haven't already, you should read my previous blog post on Custom Text Boxes in VB.net, otherwise this post might not make much sense.

So, I got most of the functionality of a good text box working today, except using arrow keys to move the caret around the text.  I tried many different approaches, but no matter what I did, arrow keys and tab were moving focus around in my form instead of being handled by KeyDown.  I went back into the EnhancedTextBox class and started to poke around the protected overrides functions to find one that might help me out, and boy did I ever find it: ProcessCmdKey.

I added this code to the EnhancedTextBox class:

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    If keyData = Keys.Up Or keyData = Keys.Down Or keyData = Keys.Left Or keyData = Keys.Right Then
        OnKeyDown(New KeyEventArgs(keyData))
        ProcessCmdKey = True
    ElseIf keyData = Keys.Tab Then
        OnKeyPress(New KeyPressEventArgs(Chr(9)))
        ProcessCmdKey = True
    Else
        Return MyBase.ProcessCmdKey(msg, keyData)
    End If
End Function

Now I'm able to capture KeyCode.Up, KeyCode.Down, KeyCode.Left, and KeyCode.Right in the KeyDown event handler and I can receive Tab as a keypress (ASCII code 9) in the KeyPress handler.  So that's spiffy.
Here's what the text editor control looks like right now.


It doesn't do syntax highlighting yet, but Rome wasn't built in one day, either.

Custom Text Boxes in VB.net

A game engine is only as useful as the tools used to create games for it.  Following this line of logic, it seems obvious that I also need to create a game studio to go along with the game engine.  Aside from creating sprites, animations, and the like, a good game studio is going to have a good syntax-highlighting text editor for writing scripts.  Now, I don't know how many people have tried to created a syntax-highlighting text box before, but I can say that I have, and that it is not as easy as it sounds.  I don't just want syntax highlighting, but also automatic pretty-code formatting.  If you have ever used Microsoft Visual Studio, you already have an idea of what I'm talking about. 

The obvious solution would seem to be a RichTextBox.  We could create an even handler that consumes the OnTextChanged event, and parse the the text in the box.  We would look for tokens and change their color in the RichTextBox, for example, green for comments, blue for keywords, red for text, and so on.  I did just this, using regular expressions to locate keywords, comments, and double quote delimited text, and colorize them.  Unfortunately, this doesn't help with code formatting, only coloring.  It also is SLOW!  Even only handling highlighting on a single line basis, typing even moderately fast would cause the RichTextBox to stop updating text as the regex routine ground down to a near halt.  Handling pretty code formatting is an equal nightmare, as indenting and text replacing kept moving around the system caret (the cursor where you type), and screwing up text entry when typing fast.

So, I've set off on creating my own custom UI control.  I figure since I'm making the whole thing from scratch anyway, I might as well have some fun with it.  I've decided to make the CodeControl a text-box like region with scroll bars (horizontal and vertical), no word wrapping (terrible for coding anyway), and a combo box at the top.  The combo box would populate a list of declared functions that the user can choose from to auto-scroll to the definition of that function.  I thought it would be a nice touch.

To pull this off, we need to consume KeyPress, MouseClick, and OnPaint events.  We need to override any default rendering so we can paint it how we want, including formatted and colored text.  We need to implement our own caret (text cursor), so we can account for it when formatting code.  We also need to handle text selecting, drag-drop moving, copy, paste, cut, undo, and redo for maximum user friendliness.  Oh, and the control has to run fast and efficient. 

To prevent reinventing the UI wheel, it would be nice if we could inherit our new control from an existing UI control.  Text box is an obvious control to inherit from, but TextBox has a system generated caret that we can't (easily) hide and show, except giving and taking focus which messes with our KeyPress handler.  So TextBox is out.

PictureBox is designed to be efficient to draw to using GDI+, and includes many optimizations by default to increase performance.  PictureBox has a major limitation though: no KeyPress event.  There is a KeyDown and KeyUp event, but they don't ever fire because PictureBox is incapable of accepting focus.  So PictureBox is out.

RichTextBox has the same issue as TextBox, so it is out.

Panel can't accept focus either, so it has the same problem as PictureBox.

GroupBox doesn't accept focus normally, but if we call the Focus method from MouseClick event, and watch our GotFocus and LostFocus events, we can appropriately turn on and off our custom caret.  GroupBox doesn't normally accept focus, but for some reason it does have the KeyPress event (I suspect it is inherited from something, and is only there to pass input to child objects.), although the MSDN says that KeyPress never fires, I called Focus, and pressed some keys, and sure enough KeyPress was firing, so that's good. 

So it looks like GroupBox has all the necessary events and functionality we need to implement a new text box, but a group box doesn't really look much like a text box.  That's easy enough to change.  We can use the paint event to Graphics.FillRectangle the ClientRectangle to white, then draw a dark gray rectangle around the ClientRectangle area.  That should do it for looks.  Only trouble is GroupBox is not a control optimized for user drawing.  Anything we paint is going to cause flickering on the control when we refresh, which is going to happen every keystroke, and every 1/2 second for the caret blink.  Ugh.

I added a project "SyntaxTextBox" to the "Game Studio" solution, set the build order so that SyntaxTextBox was a dependancy of the project "Main Editor".  Then I added a reference of SyntaxTextBox to the Main Editor project.  I added a user control "CodeControl" and a class "EnhancedTextBox" to the SyntaxTextBox project.  I right clicked SyntaxTextBox and click Build.  Then Save All

Now, on the Main Editor project, I can add an instance of the CodeControl to the main form.  This allows me to debug my custom user control as it edit it.  I just have to make sure I always right click the UI project and click build before my changes will show up under the main form.

On CodeControl, I added a combo box, a HScroll and VScroll.  I opened the code view on CodeControl, and created a public instance WithEvents for the EnhancedTextBox.  In Public Sub New of CodeControl, I added the control to Me.Controls (after InitializeComponent), set the location, size, and anchor properties.

In EnhancedTextBox, I inherit Groupbox in Public Class EnhancedTextBox, which essentially turns my EnhancedTextBox into a groupbox (for now).

I built the project, and added the control to the main form and build the project.  As I expected, the custom control now has a combo box at the top, scroll bars on the right and bottom, and a group box filling the rest of the control.

Now on to turning the group box into a text box.  I opened the code in EnhancedTextBox, and added the methods Public Sub New, Protected Overrides Sub OnPaint, and the Public Event DrawMe.

Here's the EnhancedTextBox class now:

Public Class EnhancedTextBox
    Inherits GroupBox

    Public Sub New()
        MyBase.New()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True)
        Me.UpdateStyles()
    End Sub

    Public Event DrawMe(ByRef e As System.Windows.Forms.PaintEventArgs)

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        'don't need this, we are doing user painting
        'MyBase.OnPaint(e)
        'clear client area
        e.Graphics.FillRectangle(Brushes.White, Me.ClientRectangle)
        'draw boarder
        e.Graphics.DrawRectangle(Pens.DarkGray, Me.ClientRectangle)
        'call the draw event where text painting will occur
        RaiseEvent DrawMe(e)
    End Sub

End Class

SetStyle allows me to set flags for the control that determines how it will behave. 
AllPaintingInWmPaint effectively disables the default group box painting code
UserPaint tells the blitter that I'm going to be painting, so don't update the screen until I'm done.
OptimizedDoubleBuffer tells the blitter that I want to draw to an off screen plane, then present the whole control at once instead of drawing each item to the screen one at a time.  This gets rid of flickering.

Now in the CodeControl, we have a group box that isn't a group box any more, but will still behave as if it were one.  We need to change that.
We need to write a handler for MouseClick.  This will manually set focus on the group box so that KeyPress will function.  This method will also need to store the mouse_x, and mouse_y into a public variable, and flag that a click occurred in the group box. 
We need to write a handler for GotFocus that turns on a timer control (500 msec interval), and flags the caret on.  GotFocus will also trigger a refresh for the groupbox.
We need to write a handler for LostFocus that turns off the timer, and flags the caret off.
We need to write a handler for the timer_tick that toggles the carret on/off.
We need to write a handler for KeyPress that handles keystrokes (updating text manually, checking for keywords, setting color, etc).  I will use a select case block to determine what keys were pressed, and check for current states, such as "is text selected?  This key code replaces that text", and "are we in insert or overwrite mode?".  Some reference codes: Asc(e.KeyChar): 8 = Backspace key, 9 = Tab Key, 12 = Enter Key.  27 = Escape. 
We need to write a handler for KeyDown/KeyUp that handles Shift, Alt, Control, Arrow keys, F1 .. F12, Delete key, Page Up, Page Down, Insert (for insert/overwrite mode), and alt-menu key. 
We need to write a handler for the custom DrawMe event that actually draws the text on the screen.  If the click occurred flag is set, we need to calculate the caret line and column location while drawing the text on the screen.  This is not so obvious to do since some fonts are proportional.  We'll have to check each character as we draw it to see if the mouse clicked over it's location on screen.
We need to write a handler for MouseDown/MouseMove/MouseUp that tracks mouse movement while buttons are down to handle text selection.  I haven't worked out exactly how this will work, but I have a general idea that it will be tied with the set caret code from MouseClick.

Some of these handlers I'm working on now, and are in a basic skeleton format.  The result is I have a marginally functional text box that I can begin to do whatever I want with it.
There is a lot of code still to be written before this custom text box is ready for prime-time though.  Sounds like some straightforward programming fun to me!

Hopefully, this will give someone a basic idea for how to implement their own custom UI elements.

Sunday, January 8, 2012

Expression Evaluation

Expression evaluation is one of the most difficult and complex parts of this project, but it's one of the most important.  Most data processing an any program is going to involve expressions, so it is essential that I optimize this process as much as possible.  I created 4 different flow charts approaching this problem from different angles, and think I've got a good handle on how this is going to come together. 

The first way I tried involved a large for loop that would cycle through each character in the expression, and use a state machine to separate the characters into numerals, or variables, or operators.  It used a select case to cycle through the operators, and evaluate them one at a time for left and right operands.  I'm not sure this process would work, as it doesn't handle order of operation very well.

Next idea was to pre-parse the expression before trying to evaluate it.  This would involve a large loop similar to the first idea, but no evaluation would happen in stage one; it would just parse up the terms into numbers, variables, operators, etc.  These terms would be stored in an array that the second phase would then evaluate.  It looked like the second loop would be much more compact, since it would just be a bunch of select case statements over and over.  Order of operations would not be such a problem in this model, as the evaluation routine could loop over the collection of terms, evaluating the highest precedence operators first, and working its way down through highest precedence to the lowest (parenthesis, multiplicatives, additives, relational comparisions, assignment, sequential evaluation, etc).  I liked the way this one was organized, but it would require multiple (many, many actually) loops over the terms, moving them around, combining them, and sorting them, over and over.  This would surely require a lot more processing time than I wanted to devote to this.

I thought about using dynamically compiled C to evaluate the expressions, and did some research into what would be involved in this.  I decided against it as it would require even greater processing time than the previous idea.

Finally, I settled on a single-pass method that uses recursion to evaluate expressions, selectively processing or deferring for the next operand/operator in the expression.  This method seems the most promising, and it's the one I'm going with (unless I think of a better way).

Here's the basic idea for how this works:
1) A starter function is called.  The function takes 3 parameters, the ScriptObject byref(containing variables, structs, enums, datablock, etc), the expression (as a string) byval, and a variable to hold the return value of the evaluation, byref.  The function returns an integer type enum, ErrorCode, that indicates if something went wrong.  Before it does anything, it makes a backup copy of the ScriptObject, including all Variables, structs, enums, datablock, everything.  This allows all processing to be reverted in the event of an error occuring during evaluation.  Variable contents could be left in a very inconsistent state in this case, and the only choice is to revert everything and return an error code.  This will allow easier debugging, since analyzing a total mess of jumbled data is a nightmare.

2) The starter creates a few variables to track the progress of the evaluation, and control the other functions.  Pos is the character position in the Expression where evaluation is currently at.  TermIdx is an auto-increment index assigned to each term as they are processed, for easy identification during processing.  ExpTerm is a structure to contain parsed expression terms.  ThisTerm is a var of type ExpTerm that holds the currently processing term.  LastTerm is a var of type ExpTerm that contains the previous term that was handled (or left operand for operators that take two terms).  RightTerm is a var of type ExpTerm that holds the next term to be processed (or a right operand for operators that take two terms).  For operations that need to look-ahead in the expression to make decisions (for example, declaring variables takes a ThisTerm - DataType, a RightTerm - Variable Name, and needs to look ahead to see if there are array subscripts to choose wrether to make a simple variable or an array), RightTerm2 holds the look-ahead term.  If the RightTerm2 turns out to be something unexpected, or unusable for ThisTerm, RightTerm2 is moved into NextTerm for safe keeping.

3) The Starter calls a function that parses the expression into terms, GetNextTerm.  This function takes 5 parameters, and return an ErrorCode.  Param 1: ScriptObject that contains variables, structs, enums, datablock, etc; Param 2: Expression to be parsed, Param 3: NextTerm, byref, that will be populated with the NextTerm parsed; Param 4: Pos, the position in Expression to resume parsing at; Param 5: TermIdx, the auto-increment index for the retrieved term.  This function loops through characters in the Expression, starting as Pos, ignores whitespace until the first character is found.  It checks the character for operator symbols, and if found, it identifies the operator and stores in NextTerm. 

If the first character found is alphanumeric, it builds a string Symbol until a non-alphanumeric character is reached.  It then checks Symbol to see if it is numeric: if so, it checks if the stop character was a decimal point, and continues to build the number if it was.  Once the number is fully parsed, it checks it against some constants to see what kind of numeral is it, floating point, 32-bit integer, or 64-bit interger, based on size, and decimal place existance.  It creates a Term out of the parsed info and returns.

If the Symbol is non-numeric, it assumes some sort of moniker is present.  It first checks to see if Symbol is a primitive data type: if so, it returns the Term as a DataType.  Next, it searches through the Moniker Index to find out if Symbol is an enum type, struct type, functoin call, or variable.  If enum or struct, it returns the DataType.  If function, it returns a function call Term.  If variable, it grabs the details of the variable from the VarCatalog, and returns Variable Term.

Lastly, if it still hasn't identified Symbol, it returns an UnknownMoniker Term.  This isn't an error condition, it just indicates that this term could be a new variable declaration.  Further evaluation will be required to determine if the Moniker is actually a reserved work and an error should be thrown.

4) Now that the first Term is parsed and ready to process, the Starter invokes the recursive Evaluate function.  This function takes 7 parameters, and returns ErrorCode.  Param 1: ScriptObject byref; Param 2: Expression to evaluate; Param 3: Result of the evaluation, byref; Param 4: Pos, byref; Param 5: TermIdx, byref; Param 6: ThisTerm; Param 7: LastTerm. The function is called with all available info at this point, and LastTerm is assigned Nothing, since there wasn't a last term.

5) Evaluate runs a Select Case against the type of ThisTerm.  For each possible Term type, RightTerm is populated if needed, then RightTerm2 if populated to check for precedence.  If the current term is higher priority than RightTerm2, the current Operation is evaluated and then Evaluate is called recursively; The results of this operation are LeftTerm, RightTerm2 becomes ThisTerm, and all other variables are passed on as well.  The Evaluate returns, its Result is passed on as this recursion's Result, and the function returns.

If RightTerm2 is higher precedence, then Evaluate is called before evaluating ThisTerm; LeftTerm is populated with RightTerm, and ThisTerm is populated with RightTerm2, all other vars are passed on to the recursion.  When Evaluate returns, its Result will contain the results of processing, and those are used as RightTerm.  The Operation ThisTerm is then evaluates against LeftTerm and Result, and the results are returned in Result, and the function returns.

6) After all terms have been evaluated, RightTerm2 will start populating with EmptyTerm, which is the lowest precedence priority, and all operations will complete, and if they were deferred, they will evaluate now.  Then each recursion will get a EmptyTerm when they populate RightTerm2, and eventually all Evaluate recursions will return, and execution will fall back to the Starter.

7) Starter will then analyze the ErrorCode that was returned.  If everything is ok, the returned Result will be packaged into this function's Result parameter, and execution will return to the main code execution body.  All variable assignments will be committed at this point.  If something goes wrong, and the code hasn't indicated it can handle the exception (unhandled exception), then execution is halted so I can analyze the two data blocks (the original and post-mortem versions) and the passed expression and all parsed Terms to find out what went wrong.  If the code indicates it handles exceptions, then ScriptObject will be reverted to the backup and an ErrorCode will be returned.  This allowed the script code to continue without worrying about garbled datablocks.


So, that's the plan.  I think it is a workable solution to the problem.  If anyone has any ideas or suggestions (or potential pitfalls), I'd love to hear them in the comments.

Saturday, January 7, 2012

Script Engine Flow Chart

I'm close to finalize the design of the scripting engine, so I'm posting some preliminary pseudo code.

The general flow for script execution is: Load, Execute on Update, CleanUp


First, the function that loads a script from a URI (Uniform Resource Identifier)
Function LoadScript(URI As String) As Error
   Dim Script As ScriptObject = Nothing
   If IsLegalPath(URI) Then
      Script = LoadScriptFromFile(URI)
   ElseIf IsLegalURL(URI) Then
      Script = LoadScriptFromURL(URI)
   Else
      Return Error.UnrecognizedURIFormat
   End If

   If Script Is Nothing Then
      Return Error.LoadingScript
   End If

   Dim ErrCode As Error = PreParseScript(Script)
   If ErrCode <> Error.none Then
      Return ErrCode
   End If
End Function

Execute on Update is executed just before each frame is called.  Execution of scripts takes place in a single function, and the function returns when the update is complete and the graphics engine can begin rendering objects to the screen.  The first time this function is called for a script, it begins execution of the script at the top of the main() function.  On subsequent calls, it resumes execution where it left off before.

Function ExecuteScript(Script As ScriptObject) As Error
   Dim ErrCode As Error
   If Script.PC = -1 Then
      ErrCode = CallScriptFunction(Script, "main")
      If ErrCode <> Error.none Then
         Return ErrCode
      End If
   End If

   ErrCode = RunCode(Script)
   If ErrCode <> Error.none
      Return ErrCode
   End If

   Return Error.none
End If

There are structure and enums that hold information about identified functions, variables, structs, enums, and the locations in the script code they are found.  These structures hold information such as data type expected, memory contents of variables, and a tree-like structure for tracking structs and arrays.  The idea is that the PreParse function can identify all this info before execution begins, thereby speeding execution of the code. 

The function RunCode is where all the action is at.  It gets symbols from the script one at a time, and interprets what they mean.  The whole function is inside a big loop, and repeatedly gets symbols and interprets them, until a command is encountered that flags the script's readiness to update the display screen.  Once the script flags that it is done running for this frame, the function returns an Error code (Error.none for success), and the graphics engine begins to update the world with data processed and returned by the script.

All script state information about nesting, function calls, variable contents and scope, and instruction pointer, are all contained in the ScriptObject.  This allows the script to trigger an update at just about any point and safely expect execution to resume exactly as it was upon next update cycle.

When the script is finished up (the game is over) the main() function ends, and memory cleanup is initiated.  After this cleanup process, the game engine is notified to shut down, and objects are disposed, such as sounds, images, models, network connections, etc.  Then the engine exist.

There is one big part missing from this script engine so far: expression evaluation.  This topic is so long and complex, it deserves its own separate post.  Expression evaluation is likely to be the most complex part of the entire game engine.  I envision a recursive token parsing evaluating system, and as soon as I figure out how to implement this, there will be a lengthy post about it.

More updates to come as design continues.

Tuesday, January 3, 2012

Scripting Plans

I've taken quite a few formal programing classes over the years, but none of them have even mentioned the concept of scripting, much less emulating one language with another.  I find myself asking the question "Where do I start?"  Well, it seems reasonable to search the Internet and see if anyone else has tried what I'm about to do.  As it turns out, if anyone is, they aren't advertising it to the world at large.  No big surprise there though. 

Well, I came up with a plan, a roadmap if you will, for how I'm going to pull this all together to make it work.  It starts with a formal definition of exactly what language I'm implementing.  This isn't just a matter of picking a language that already exists; I have to define what commands are going to be available, what their syntax is, and how they are to function, exactly.  I've never thought about it before, but programing languages are complex, and very difficult to describe in precise terms.

For this project, I've chosen to implement my own version of C.  I'm going to try to make it as close to ANSI C as possible, but there are going to be differences, for sure.  I've typed up a document that formally defines every data type, command, structure, and the syntaxes for all.  It helps that I'm comfortable with C, so I didn't have to do very much research in this task.  Here's a brief overview of my work so far.

Primitive Data Types:
void - indicates a function type returns no data.
int - 32-bit signed integer.
long - 64-bit signed integer.
float - 64-bit IEEE double-precision floating point number.
char - 2 byte Unicode character.
cstr - A string, similar to a c-style string, but 2 bytes per character (for Unicode support), and terminated with a two 0 bytes ( \0\0).

User-Defined Data Types:
enum - an enumeration of values.  Internally, this is the same as an int, but you can assign monikers to represent numbers.
struct - a collection of other data types that can be stored in a single variable, or used as an array.
Arrays - a collection of the same data type stored in a single variable, using subscripts to access individual elements of the array.  Can be made of any primitive or user defined data type.

Declaring variables:
primitive data types: datatype moniker [ = initial value];
enums: enum moniker { [member1 [ = value ] [, member2 [ = value] ...]] }[moniker];
structs: struct moniker { [type1 moniker1; [type2 moniker2;]] } [moniker];
arrays: datatype moniker[arraybound1][arraybound2]...;

Declaring functions:
prototype function: datatype moniker([datatype [,datatype...]]);
define function: datatype moniker ([datatype param1 [, datatype param2...]]) { statements; };

Now for some command statements.  These fall into a few categories.

Looping:
for ([init_expression]; [condition_expression]; [loop_expression]) {statements;}
do {statements;} while (condition);
while (condition) {statements;}

Condition Execution
if (condition) {statements;} [else {statements}]
switch (expression) { case const_value1 : [statements;] [break]; [ case const_value2 : [statements;] [break;] ] ... [default : [statements;] [break;]] }


For those of you who are not as familiar with c-style syntax, here's a few examples to help clarify what all these definitions mean.

Variable declaration and assignment.
int a = 4;        /* creates an int var, assigns value 4 */
int b;     /* creates int var b, default value is 0 */
b = a;    /* assigns var b the value in var a (4) */
a = 5 + b;   /* assigns var a the value of 5 plus the value of var b (4), so 9 altogether */

Array definition and handling.
int list[2];   /* creates an array variable list, with two elements */
list[0] = 2;  /* assigns the first element, 0, the value 2 */
list[1] = 5;  /* assigns the second element, 1, the value 5 */

Enum definition and handling.
enum DaysofWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
DaysofWeek Today = DaysofWeek.Tuesday;
DaysofWeek Tomorrow = Today + 1;   /* assigns the value of Today (2) + 1, to var, will = Wednesday (3) */

Struct definition and handling.
struct coordinates {
    int X;
    int Y;
};   /* creates a struct called coordinates, that contains two data fields, an int called X, and an int called Y */
coordinates Location;   /* defines a variable called Location of struct type coordinates.  You C guys will notice the lack of the struct keyword in this definition.  I'm leaving it out of my specification because it's not necessary. */
Location.X = 3;   /*assigns the X component of the Location coordinates structure the value 3 */
Location.Y = 2;   /*assigns the Y component of the Location coordinates structure the value 2 */


Looping example:
For loops are generally used when you need to run a block of code a fixed number of times.  Before the loop is started, the init_condition is evaluated.  This is generally used to create local variables for a loop counter.  Then the condition_expression is evaluated to see if the statements get execution.  If the condition_expression evaluates to non-zero, then statements are executed, else the block of statements is skipped, and the for ends. After execution of the statements, the loop_expression is evaluated, then the process starts back over at testing the condition_expression.  All parameters are optional, and if condition_expression is omitted it is assumed to be non-zero, and an infinite loop is created.  A for loop can be exited early with the break; statement, or prematurely restarted (just like it had reached the end of statements) with a continue; command.
int total = 0;
for (int count = 1; count < 5; count ++) {
    total += count;
}     /* total will be equal to 10 when this finishes */

Do loops are generally used when you don't know how many times a block of code needs to run, but you know it needs to run at least once through.  The loop condition is tested at the end of each iteration.  Do loops can be exited with a break; command.
int a  = 1;
int b = 32;
do {
    a +=1;
} while (a < b);

While loops are generally used when you dont' know how many times a block of code needs to run, and in fact, it might not run a single time.  The loop condition is tested before entering each iteration.  While loops can be exited with a break; command.
int a = 3
while (a < 100) {
   a +=1;
}

Conditional execution example.
If statements are used to test a condition, and execute statements if non-zero, and optionally execute statements if zero. 
int a = 3;
int b = 2;
if (a > b) {
    /* a is bigger than b */
} else {
    /* a is smaller than or equal to b */
}

Switch statements are used when testing an expression against multiple possible values.  Switch is preferable to a series of if statements, but can only be used to test against constant values.  Switch evaluates the expression, then begin search each case clause.  When a case is matches, execution begins following the : until a break; statement is reached.  break; sends execution to the end of the statement block.  An option default statement starts execution after the : if no previous case values matches the expression.
int a = 3;
switch (a) {
    case 1 :
        /* a = 1 */
        break;
  case 2 :
        /* a = 2 */
        break;
   default :
        /* a did not equal 1 or 2 */
        break;
}

Well, that's all the examples I have for now.  If anyone has any thoughts or suggestions about this, please feel free to post them in the comments below.

Next up, how to read this programmatically.

Monday, January 2, 2012

Scripting technical challenges

As I work on this game engine, slowly but surely I'm learning new programing strategies.  Here's something I've learned in the last 24 hours: It is one thing to write a program; it is entirely different to write a program to emulation another programing language.

Let me further define the situation here.  When you write a program, a compiler turns your code into machine language (or some sort of pseudo code anyway).  When your program is running, there are a series of transistors that physically turn on and off electricity to components of your CPU, using the electrical impulses that comprise your program's binary digits machine code to direct that activity.  The part of your CPU that gets activated begins to carry out activities by turning further transistors on and off , all in response to the pattern of electrical impulses you programed for it.  One part of your CPU causes a word of data to be read from  memory and placed into a register.  Another part might take that word of memory and perform some sort of math function on it.  Other parts of your CPU send signals out to your video card, and those signals further instruct that video card to read memory.  Those signals cause the video card to generate a new signal to your monitor, allowing you to read this excessively verbose test.

The point is, all the processing happens at a physical level in the CPU; physical transistors being turned on and off by our inputs and the program's instructions.  This all happens extremely quickly, and all in the background, so it is easy to forget what is happening at the lowest levels of our machines.

When your program supports scripting, you have to read in some sort of file, and the patterns of characters tells your program how to carry out certain pre-programmed tasks.  If you want your script host to be able to pop up a message box for the user, you have to define a pattern of characters that your program can recognise, that direct it to do so.  Your program spends a great deal of time analyzing the characters in this script file, and your program has to be careful how much time it devotes to doing this.  If your program is a game engine, you will already be spending a great deal of time telling the video card where and how to display any number of graphics on the monitor.  You don't want to take away from that time, or the game will start running slower. 

To compare how quickly the physical CPU is at running a program to a piece of software analyzing one and emulating it on the fly, is very difficult.  I would estimate the emulation to be many hundreds of times slower; perhaps even thousands of time slower.

Imagine you want your game to run at 60 frames per second.  That means your program has 1/60th of second (or about 0.0166 seconds) to check the keyboard, mouse and controllers, figure out what that input means to the game, and take action on it, update all of the physics for all the objects in the game, then finally tell the video card where and how everything is supposed to look on the monitor.  Online games also have to deal with incoming data from the server, updating the world objects accordingly, and prepare and send packets of data back to the server to let it know what input the game got from the user. 

Computers are fast, but this can be a LOT of work to do in such a short amount of time.  And, the game isn't the only thing the computer is doing at that moment in time.  Your program doesn't get to run continuously when it is running.  Instead, windows assigns "time slots" for your program to run in, called a quantum.  A quantum is a unit-less measure of CPU time.  For most desktop computers, the 3 quantum is going to equal about 10 milliseconds on a single processor system, or 15 milliseconds on a multi processor system.  How many quantum your program gets for execution each time it is scheduled depends on a number of very complex factors, but can be anywhere from 3 to 12 quantum. 

Once you start to realize that your program doesn't necessarily get time slices that line up with your desired 1/60th of a second, you notice there's a problem here.  If your program spends its entire quantum of time running a script, you will miss your window of opportunity to display an updated frame.  Too much of that, and your program will run very choppy.  Your monitor's vertical refresh pulse can't wait around for your game to catch up, of the display will start to flicker, a subjectively even worse condition.

So, I'm going to work on these challenges as I design the script engine, and if I come up with anything clever, I'll be sure to post them.

Sunday, January 1, 2012

C-Scripting developments

After spending the entire night working on this, I've come up with what I hope is a workable plan.  Instead of making a game engine and tagging on a script language to control it, I want to rework the entire engine to focus primarily on the script language, then adding functionality to the language by way of APIs.  This would reshape the entire project to wrap all the game engine elements around the scripting language; I think this may be the best way to build the game engine.

Anyway, I'm working on a language syntax definition document, and as soon as it's ready, I'll post it here for comments and suggestions.  I will also be putting together an API so the script language can control things in the game engine. 

As it is now, XNA gives us two important functions, Update, and Draw.  Update is where all the game logic is supposed to take place, and Draw is where all the game rendering happens.  Initially, I wanted to run the scripts in the Update function, and have a fully built and updated world object that the Draw function can quickly render to the screen.  However, I recognize that there are two completely different paradigms here I am trying to balance: procedural, and event-driven programming.

In a procedural design, there would be one script running at a time.  It would be responsible for loading, controlling, displaying/using, and disposing of all game resources.  This means that a game script would basically create a bunch of objects and loop through them every frame update processing game logic and what-not.  This is the easiest to implement I think.  Scripting would happen exclusively in the Update function, and any rendering APIs would build a world object that the Draw function would then render.  After Draw finishes, Update would be called again, and the script would pick where it left off last frame.  The scripting language would need a command to indicate when it is ready to sync, thereby pausing execution so the prepared game scene can be presented to the user.

In an event-driven design, I can imagine a "master" script creating game objects, and attaching scripts to each object.  As the game runs, users click on objects and type on the keyboard, objects collide, or one object sends messages to other objects. These actions trigger messages to be dispatched to each object.  Objects can bind certain message types to functions, thereby creating event handlers.  Think of windows programming, where you click on a button and the program executes code in response to that.  The same sort of thing is going to be happening in the game.  One strength of this is that independent agents can be running from their own namespaces, meaning that a player can be controlling their character, while an enemy stalks that player down or plans a strategy.  These sections of code can inherently be run in parallel, meaning the game can take advantage of modern multi-core processors.  Unfortunately, there are two big downsides here. 1) designing a game to run in such an environment is extremely difficult and complex.  When bugs creep in, finding them and fixing them can be very challenging, and as the complexity of the game goes up, you begin to see emergent behavior in the independent agents.  The goal of programming this way is to create the emergent behavior to be exactly what you want, and have a very good game.  2) designing a game engine to work this way seems to be extremely complex.  Instead of having a script interpreter, and a few classes for handling custom user data, now we have a full inter-process messaging system and process queue.  It's kind of like developing a mini-operating system instead of just a single program.

So for now, I'm going with the procedural programming paradigm, but I'm always open to comments.  If you have an opinion one way or the other, feel free to share them and discuss below!

Saturday, December 31, 2011

Scripting in VB.net

One thing that all good game engines require is scripting support.  Scripting is even useful for non game engine programs.  Currently, there are limited options available in this department for most VB.net developers. 
I started off using an extremely limited script system based on select-case and integer lists. 
Basically, I have something like this:

'A single command line
Structure Command
   Dim OpCode As Integer   'OpCode is the instruction to be executed
   Dim Param() As Integer   'Param() is an optional list of arguments the command needs
End Structure

'A single user variable
Structure Variable
   Dim VarName As String    'VarName is the name of the variable
   Dim Data As Integer          'Data is the information stored in the user variable
End Structure

'A script, including local variables, code, and program counter
Structure ScriptObject
   Dim Code() As Command          'List of commands the script is composed of
   Dim Variables() As Variable      'List of variables used by the script
   Dim PC As Integer                      'Points to the next line of code to be executed
End Structure

Sub ExecuteScript(ByRef Script As ScriptObject)
   With Sript.Code(PC)
      Select .OpCode
         Case 1    'Move a sprite Param(0) to location (X, Y), X=Param(1), Y=Param(2)
            GPU.Sprites(.Param(0)).Location = New Point(.Param(1), .Param(2))
            PC += 1
         Case 2    'Sets Sprite Param(0), Visibility(Param(1) [0=False, 1=True])
            GPU.Sprites(.Param(0)).Visible = IIf(Param(1) = 1, True, False)
            PC += 1
         Case Else
            Throw New Exception("Command not implemented yet.")
      End Select
   End With
End Sub

As you can see, this method should work just fine, so long as the script engine doesn't need to be too terribly complex, and the number of OpCodes (possible different commands) is relatively limited.  Now the real problem starts showing up when you try to implement Sprites, Meshes, animation, sound effects, network communications, background music, keyboard mouse and control input, reading and writing files, conditional branching, looping, and any number things that need to be implemented.  Now consider writing scripts for this engine using columns of numbers, with no labels or other indications whatsoever for what they are for or do.  Brings me to mind of early machine code programming (bleh).  What happens when you make a typo on one of the switch statements, and the wrong command is selected, or not executed at all?  Terribly difficult debugging, is what!

What I needed was a human readable, more flexible, and easier to work with scripting language.  There are many different scripting languages available.  Many game engines use LUA for its brevity and flexibility.  However, LUA is extremely complex to implement.  I thought I would start off small with an older, simpler language.  For example, C. 

So, now I'm working on a brand-new script engine based on C.  C by itself is probably not sufficient to control a game engine, but I could easily add API extensions to give the script language control over elements of the game. 

I would like the game engine to provide access to primitives, such as loading and displaying images, playing sounds, making tcp/ip connections to send and receive data, loading meshes and world grids, that sort of thing.

In my previous script methods, I would need to program every kind of function and command, every kind of game engine object, and every data processing method, into the game engine itself.  This would greatly limit the things that can be done with the game engine to only the things I program it to be able to do...specifically, it would limit the game engine to only the things that I can imagine it should be able to do.

Offloading all of that processing to a C script would simplify developing the game engine, and more importantly it would allow the scripter to determine what the game engine can do instead of just me.  Implementing a powerful scripting language would enable the game engine to run any kind of game the game designer can imagine.

But, how does one implement something so complex as C?  I'd be lying if I wrote that I have all the answers to that, but I'm working on it.  I'll be analyzing this problem over the next several weeks, and as I start to make breakthroughs, I'll be posting them here!

Sunday, October 16, 2011

Full screen support!

Hooray! Update!
I've been very busy at work and school lately, but have managed to squeeze in some time to code.  It took a great deal of work, but I finally managed to get VB.NET and XNA to play nicely in Full Screen mode.  This process required me to build a formless class that inherits and implements XNA.Game.  Unfortunately, this also means that it no longer inherits Windows.Form, so many of the things that I were doing for input and rendering are obsolete and no longer function.  Oh well; by implementing XNA.Game the performance of the engine went WAY up, so that's good.
In the mean time, development of the game editor had to be suspended while I rework some of the code for the engine; no sense writing an editor for an engine that is about to be overhauled, now is there?  But don't worry!  While the engine is getting an overhaul, I'm removing many of the debug code I had to put in while in early development and implementing a new network engine I've been working on.  Instead of only using TCP for network connections, I'm planning on a hybrid of TCP and UDP;  TCP for game content distribution (such as downloading updates from a website or other server), and UDP for game client data (such as player movement updates, and other in-game network traffic).  The general scripting language I'm working on has not changed much other than adding in a few new commands here and there, but I'm considering adding LUA support down the road.  This will depend on developer interest, as personally I don't care at the moment what scripting language it uses, so long as it works!
More updates to come as development continues...

Sunday, June 26, 2011

Game Editor Development preview!

The Game Editor has some a long way, but it still has a long way to go.  If you are curious about how it is coming along, you are welcomed to download the development preview from the following link:
Game Editor Development Preview

Please keep in mind a few things when you download and test this out.  You will need the .NET Framework 3.5 client installed for the software to run.  You can get this from Microsoft at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21

Additionally, this is a development preview, so functionality of the software is a work in progress.  Many functions and menu items are non-functional, so if you click them and they do nothing, that's why.  Saving and Opening projects is very experimental, so many times it won't work properly.  There is also the possibility of the publish game function damaging files or folders wherever you point it to compile to...I wouldn't recommend using it.  It does warn you that the contents of the provided folder will be deleted, so you will be informed before anything dangerous happens.

Well, that's enough dire warnings.  Download the engine and play around with it!  There is no in-program help available, so just experiment.  I'll give you one heads up about the map editor.  To select what tiles get painted where on the map editor, you must first create a tile set and import images into it. Then click to select a tile and then click to paint that tile in the map editor.  There is a lot of broken functionality there, and I'm working on that soon.

Saturday, June 25, 2011

Game Editor Update

Development on the game editor has been chugging along nicely now.
The editor breaks the game down into logical folders.  These folders are there only to help conceptualize the game you are making, and don't actually have any bearing on the engine itself.  Here's how it is coming together so far.
General: Here you adjust basic editor settings such as the preferred file export format, and the start up script.
Tile sets: Here you import tiles for use in maps and just about all other rendering in the game.  Images linked into collections to help you organize your media.  There are no such things at tile sets once the game has been compiled, as the engine will see it all as a list of images in the end.

Maps:  Depending on what kind of game you are making, maps will be used in different ways.  For most game types, maps will be the levels, world, or zones of the game.  Your characters and other in game objects will be oriented on a map, and the player will see the maps like zones in your game.  Maps are a grid of tiles. Think of a Chess board, except of any arbitrary number of rows and columns, and each "block" can be colored by a tile from a tile set to construct the world, piece by piece.

Sprites:  think of sprites as animated objects.  You can use a sprite for your characters, or for buildings, monsters, trees, or even entire levels if you so choose.  Sprites consume much more processing time in the game engine to handle than maps, so if you are planing on making a world out of sprites, consider maps instead...  Sprites are built up of animation sequences, each with its own name.  Each animation sequence has a list of directions associated with it, and each direction has a list of images.  For example, say you want your main character to walk north, you would set your sprite to use animation sequence "Walk" and direction "North", then tell it where to go.  The sprite will automatically animate the movement based on the images associated with this sprite.  There is more to it than that, but you probably get the idea well enough for now.

Sounds: Every good game has sound in one way or another.  Sounds can be anything from sound effects of gun shuts, sword slashes, car tire screeches, or explosions.  The background music for the town your character walks around in will be considered a sound too.

Scripts:  here is the real meat and potatoes of your game.  Scripts are responsible for every conceivable action that your game will take.  A start up script (Which you specify in the general options) will be responsible for loading up basic resources needed by your game, such as main menus, character animations, sprites, etc.  The scripts will be responsible for coordinating everything that goes on in the game, and a powerful language is being developed to make this process as simple as possible, while still allowing the greatest flexibility.  Many more of these blog posts are to come that will talk about scripts, so stay tuned.

The game editor also now supports saving and loading project files.  Nothing ruins my day more than building a sample game, testing it out, needing to make one change, but being required to develop the sample game all over again from scratch because there is no save/load button.  Well, now there is, and it works quite well.

More is to come on the editor, as development continues.  Stay tuned!

Friday, June 24, 2011

Game Editor

My original plan was to write the game engine, then create a game editor that would assist developers in creating games for said engine.  However, it is hard to write a game engine when all of the test data (levels, characters, scripts, animations, etc) all have to be hand created for each test build, and as you might imagine, it gets tedious too.
It seems only logical that I should develop the game editor alongside the game engine, that way I can be sure they are compatible with each other.  Most importantly, I can create test game object in the editor, and then run them in the game engine and make sure everything is working as expected.

Therefore, I've decided to temporarily suspend the development of the game engine until after the game editor catches up with it.  I'm not TOO far along that it will significantly delay anything, and the way I look at it, nobody will be able to make anything for the engine without an editor anyway, so you'd have to wait anyhow.

The good news is, I have a really good idea for how I want this editor to work.  I'm thinking about making it a model form, meaning that it can have children windows.  The main windows will have a tree view on the left with categories of objects, like windows explorer folder view.  To do anything, you would open a folder for an object type (such as tile sets), then a list would appear under that of tile sets you've created and saved.  You could double click one to open it up, then import images into the set. 
After a tile set has been created, you can create a new map.  To draw tiles onto the new map, click the tile you want to paint in the tile set window, then click to draw that tile in the map editor.
Sprites will be similar, except they will be broken down into actions (such as walking, standing, attacking, getting hit, dying, etc) and then further into directions (north, south, east, west, etc).  Then you will import a series of images that will be looped for each direction.  There are a lot of options here that will need to be set, such as where in the image does the characters feet stand at, and what color should be regarded as transparent.
Scripts are possibly the hardest thing to implement.  Instead of making you type in scripts in the low level game scripting language (not fun, by the way), you will be presented with a text editor, and you can type in an actual scripting language.  This gets compiled into the low level language when the game is packaged for deployment (compiled). 
The beauty of this is instead of referring to objects by their game engine ID number, you will be able to declare variables of each game engine class type, such as a character sprite, or a map, and refer to them as such in the scripts.  You will be able to refer to maps, sprites, etc, using the names you gave them in the editor (such as world.map, OzarkCanyon.map, hero.spr, and such), instead of assigning a file name to a register index, and having to refer to it as some abstract number from there on out. 
For right now, I'm aiming to get at least the functionality down that I have been able to manually code in notepad, and make it so that the editor can save and load projects so I can continue working on them after stopping and closing the editor session. 
Once this is accomplished, I will return to developing the engine, one little piece at a time.  Only at that point, I'll be able to test these components As I develop them.

Monday, May 30, 2011

Back up and running!

Well, for those of you who don't know, I live in Joplin, MO, and an EF5 tornado came through on 22 May 2011 @ about 5:30 CDT.  Our house is fortunately undamaged, but we went without power for a week, which makes it hard to work on the computer.
However, I have made some improvements to the game editor.  The Map drawing feature now works, so it is now possible to create maps using tile-based map editing.  Also, the tile importer works, but I'm still trying to figure out how I want the tile editor to work, so for now tiles have to be created in a seperate editor, like MS Paint, and imported. 
Next up is collision boundary integration, I think.  I'll play that by ear as development requires it.
I hope to have more updates comming soon now that our power is back online!

Monday, May 9, 2011

Game Engine overview

When working on a game, it is important to know how your ideas will be integrated into the whole of the project.  With this in mind, I've decided to write a few articles highlighting the internal functioning of the game engine.  I'll start with an overview of the core engine, and fill in details as necessary.  Keep in mind that these are design concepts, and some of the functionality listed here is not implemented fully yet.

Program start:
Load localization settings
Locate and load startup scripts
Query graphics adapter properties
Set main window settings, and set up graphics/audio device for rendering
Main Engine Loop:
   Get keyboard/mouse inputs
   Get network packets
   Execute scripts
   Update sprite animations
   Update vectors/state data
   Send network packets
   Render audio
   Render graphics
End Main Engine Loop
Cleanup loaded game resources
Release graphics/audio adapters

And now for the explanations.

Load localization settings:
Different regions of the world process data differently, and display it to users differently.  For example, some places use commas for digit grouping, and others use a period.  These settings are saved in the operating system, but we have to retrieve them in order to use them.  This happens here.  Also, translation files are loaded at this point.

 Locate and Load startup scripts:
Because I want the engine to be as customizable as possible, all game engine activity will be governed by scripts, including the startup and initialization of the engine itself.  The script engine will be responsible for setting up the graphics and audio adapters, including choosing display resolutions and setting audio sample rates. 

Query graphics adapter properties:
At this point, the engine will collect a list of adapters and possible resolutions and color depths that can be used. 

Set main window settings, and set up graphics/audio device for rendering:
The control of the engine is turned over to the script engine at this point.  The script directs setting display properties, and getting the hardware ready for the game.

Get keyboard/mouse inputs:
Once every game frame, keyboard and mouse states are updates, and if a controller/joystick are in use, the states of them are pulled.

Get network packets:
If a script has initiated the network adapters, then at this point any newly received packets are processed, decoded, and the data is fed into the script engine ready for processing.

Execute scripts:
This is where the real work gets done in the engine.  The script engine is in charge of loading resources, discarding them, and all internal workings of the game's finite-state machine.  This part of the engine is by far the most complex, and therefore I'll write a separate article about it later.

Update sprite animations:
Many of the commands in the script language are dedicated to making it easier to write games.  Many of them are aimed at automating many things in the game, including sprite animations.  Those are handled here.

Update vectors/state data:
Just like the sprite animations, many commands handle automated motions (vectors).  These are updated here.

Send network packets:
If the network is in use, once all of our state data is processed, we then transmit any updates to this to connected client games.

Render audio:
Any sound effects that have been triggered will be started here, and any background music that is playing will be updated as well.

Render graphics:
Now that all of the state data have been updated, we can begin rendering the graphics.  This is by far the most processor time consuming part of the game engine.  An article will be devoted to this later.

Cleanup loaded game resources:
Once the scripts indicate the game should close, all the resources that have been loaded will be cleaned up, and all processing threads will be asked to close.

Release graphics/audio adapters:
All graphics/audio adapter resources that have been allocated will be released at this point.


I'll write articles later on that cover the more detailed processes, specifically the network engine, graphics rendering, and the script engine.

Graphics Designers Wanted

Hello again,

I've invited a co-author to join me on this blog: my brother Danny.  He has a lot of great ideas for several games that we've wanted to make into a real games for years now.  We are going to need graphics, lots of them.
He has all the ideas for how he wants the game to look, and I'm working on making the engine capable of running it.  We'll try collaborating via this blog for now, but I'm willing to set up an actual message board forum if enough people request it, or if this blog does not work out well.

Let me know what you think in the comments.

Sunday, May 8, 2011

VB.Net developer blog

Hello,
I've decided to start a blog where I can post my thoughts and some code related to the VB.Net game engine I'm developing.
For years, I've wanted to make my own video game.  I want to make a MMORPG, or possibly an RTS game.  However, ideas for such games are hard to come up with.  So after giving it much thought, I've realized that it's not so much the game that I want to make, as it is the game engine that I really want to learn how to make. 
Now, making a game engine is no trivial task, and I do not take it on lightly.  I have given a great deal of thought for how a game engine could be made.  Most game engines are targeted toward a specific genera, or type of game.  For example, the Unreal engine targets first person shooters.  I want my game engine to be generic enough to be used for nearly every conceivable game type.  What I don't want is a VB.Net wrapper around an API. Microsoft already created that, and they called it XNA Game Studio.  What I want is a game engine that actually automates as much as possible, and can be controlled with a relatively simple scripting language. 
Since this is such a massive undertaking, I've decided to start small, and work my way up.  In the interest of simplicity, I'll start out with a simple tile engine, and add sprites, keyboard and mouse input.  Once this is working properly, I'll put together a network interface for both Client-Server (MMO type games), and peer-to-peer (for Lan type games).  And finally, background music and sound effects.
Once this is all working, the engine will be ready to start developing games for. 
I already have a good start on all of this, and am working on a game object editor to help simplify the task to testing the engine, and eventually this will be the official game editor for the engine.
Updates as they come...