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!
A blog about game development, VB.NET, and other such things related to my Work-In-Progress game engine.
Search This Blog
Sunday, January 1, 2012
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!
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...
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.
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!
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.
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!
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!
Subscribe to:
Posts (Atom)