Jump to content

  • Log In with Google      Sign In   
  • Create Account

Digital adventures through the third dimension

XML in UDK using DLLBind

Posted by , 07 March 2012 - - - - - - · 1,539 views

Hello everyone,

A while ago I started on a dll to process XML in UDK using DLLBind and C#. I have been extremely busy lately, so I decided to take what I had and throw it up on the internet. It is not 100% (It probably has bugs and can't generate xml yet), but it might help someone. I take no responsibility for it, and it is very in development code, but enjoy!

http://code.google.c...dk-xml-library/

This is the stuff I talked about in a previous journal entry but a practical example.


Using C# Managed DLL's in UDK (or exposing managed dlls in an unmanaged application)

Posted by , 15 July 2011 - - - - - - · 7,166 views
UDK, C#, Managed DLL, DLLBind and 2 more...
Hello everyone,

Today I would like to share a technique I researched in order to allow DLL files created in C# to be used in the Unreal Development Kit. I posted a very similar tutorial to the one I am going to post today on my blog on the UDK forums, however since not everyone frequents that site I will post a more detailed version here for the GameDev community.

Note: The steps outlined here might be a bit advanced if you are just starting out. If you get stuck feel free to ask questions, however you may also wish to learn more about what you are doing before attempting this.


The problem

So you want to use the DLLBind feature of UDK in order to add capabilities that you need for your particular project. However what if you are not a C guru or are more comfortable with using a managed language? Well you could say "I will simply create my DLL in C#!" however that will prove problematic as the C# dll will be using managed code which is far different from an unmanaged DLL (managed code is not a direct binary file but gets turned into IL and then there are issues with export tables and all sorts of other fun technical bits that you can read in a number of much better worded articles).

Possible solutions

If we had access to the C++ code of UDK we could use various schemes to interopt with our DLL like PInvoke or Com interop, however we are stuck with the DLLBind mechanism that UDK provides to us. We need to work within the confines of what it expects and so we are left with a few options.

The first is to write two DLL files. One that is our managed DLL and then write a C/C++ wrapper DLL that allows it to interact with DLLBind. This solution is a big pain because then we are forced to use C/C++ anyway! It makes writing the DLL in C# very unappetizing.

The second is to dissemble the DLL into IL code and manually add a VTable/VTable Fixups. This is possible but a ton of work and can be a bit nerve racking (for instance now you must learn IL and hope you don't screw something up).

The third (and the option I will present in this tutorial) is to use a template to allow unmanaged DLL exports from C# (using an MSBuild task that automates a lot of the work for us).

Unmanaged Exports Template

The very first step that we will need to do is to acquire the Unmanaged Exports Template from Robert Giesecek. His template will automate a lot of the work necessary for allowing our C# dll to be used in UDK. Essentially it will provide unmanaged exports that we can then call in DLLBind!

Follow the steps the site outlines to install the template. It just took putting the entire zip file in the ProjectTemplates directory. One thing that sort of tripped me up is that you locate the required folders through the My Documents folder and not Program Files (I guess I should have read it a bit more carefully!)

Then we can create a project based off of his template.

A Simple Example

I started with a very simple test DLL to test the capabilities of the approach. Here is the C# code I used:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;

namespace UDKManagedTestDLL
{
   internal static class UnmanagedExports
   {
  	[DllExport("GetGreeting", CallingConvention = CallingConvention.StdCall]
  	[return: MarshalAs(UnmanagedType.LPWStr)]
  	static String GetGreeting()
  	{
 		return "Happy Managed Coding!";
  	}
  	
   }
}

I compiled this DLL and put it in the User Code folder. I am using Windows XP so I built my DLL as a 32 bit dll, however if you are running a 64 bit operating system then you will want to change the steps appropriately. The MarshalAs is a way to tell C# how to marshal the return string to the unmanaged code. This allows us to control how the managed types are transfered to the unmanaged types of UDK.

Then I created a class in UnrealScript (Which was named TestManagedDll.uc (which should be obvious as that is the class name, but I thought I would point it out).
) that contained the following:

class TestManagedDLL extends Object
	DLLBind(UDKManagedTestDLL);

dllimport final function string GetGreeting();


DefaultProperties
{
}

Which I could call from my cheat manager like:

exec function testdll()
{
	local TestManagedDLL dllTest;
	local PlayerController PC;
	dllTest = new class'PFGame.TestManagedDLL';
	foreach WorldInfo.AllControllers(class'PlayerController',PC)
	{
		PC.ClientMessage(dllTest.GetGreeting());
	}
}

So then I ran it and saw in my results:

Posted Image

Passing Parameters


Right then we also would like the ability to pass parameters and we can do that like so:

  	[DllExport("GetGreetingName", CallingConvention = CallingConvention.StdCalll)]
  	[return: MarshalAs(UnmanagedType.LPWStr)]
  	static String GetGreetingName([MarshalAs(UnmanagedType.LPWStr)] String name)
  	{
      	return "Happy Managed Coding " + name + "!";
  	}

With:

dllimport final function string GetGreetingName(string name);

and

exec function testdll(string greetName)
{
	local TestManagedDLL dllTest;
	local PlayerController PC;
	dllTest = new class'PFGame.TestManagedDLL';
	foreach WorldInfo.AllControllers(class'PlayerController',PC)
	{
		PC.ClientMessage(dllTest.GetGreetingName(greetName));
	}
}

produces:

Posted Image

Reading Files

I assume a lot of people will want to use this technique to write C# DLL's that use .NET for working with files, since the UDK support for reading various file formats is so low. In order to do that we need to get the directory that the DLL is in, so that we can locate our files appropriately. We can do this using Reflection.

  	public static String GetAssemblyPath()
  	{
      	string codeBase = Assembly.GetExecutingAssembly().CodeBase;
      	UriBuilder uri = new UriBuilder(codeBase);
      	string path = Uri.UnescapeDataString(uri.Path);
      	return Path.GetDirectoryName(path);
  	}

  	[DllExport("ReadTxtFile", CallingConvention = CallingConvention.StdCall)]
  	[return: MarshalAs(UnmanagedType.LPWStr)]
  	static String ReadTxtFile([MarshalAs(UnmanagedType.LPWStr)] String name)
  	{
      	string retVal = "";
      	StreamReader test = null;
      	try
      	{
          	test = new StreamReader(Path.Combine(GetAssemblyPath(), name));
          	retVal = test.ReadToEnd();
      	}
      	catch (Exception ex)
      	{
          	retVal = ex.Message;
      	}
      	finally
      	{
          	if (test != null)
          	{
              	test.Close();
          	}
      	}
      	return retVal;
  	}
   }

You should then be able to put a file in the same folder as the dll and then load it up and get the contents.

It also needs:
using System.IO;
using System.Reflection;

So it should be perfectly possible with some rudimentary knowledge to make dlls that make use of XML, files, ect.

Returning and Passing structures

NOTE: The following content may or may not be the best way to approach this problem. I will share what I have so far as a starting point, however you may wish to investigate this matter further. The use of IntPtr can be error prone and buggy but sometimes custom marshalling is the only way to solve particular problem domains when doing this sort of work. I have done some use of using "ref" and letting it handle this sort of marshaling for me, however it does not appear to work in all circumstances.

  	private static IntPtr MarshalToPointer(object data)
  	{
      	IntPtr buf = Marshal.AllocHGlobal(
          	Marshal.SizeOf(data));
      	Marshal.StructureToPtr(data,
          	buf, false);
      	return buf;
  	}

  	struct MyVector
  	{
      	public float x, y, z;
  	}

  	[DllExport("ReturnStruct", CallingConvention = CallingConvention.StdCall)]
  	static IntPtr ReturnStruct()
  	{
      	MyVector v = new MyVector();
      	v.x = 0.45f;
      	v.y = 0.56f;
      	v.z = 0.24f;

      	IntPtr lpstruct = MarshalToPointer(v);
      	return lpstruct;
  	}

where:

dllimport final function vector ReturnStruct();

and:

exec function testdll()
{
	local TestManagedDLL dllTest;
	local PlayerController PC;
	local Vector v;
	dllTest = new class'PFGame.TestManagedDLL';
	foreach WorldInfo.AllControllers(class'PlayerController',PC)
	{
		v = dllTest.ReturnStruct();
		PC.ClientMessage(v.Y);
	}
}

we get:

Posted Image

The other direction is also possible:

  	private static object MarshalToStruct(IntPtr buf, Type t)
  	{
      	return Marshal.PtrToStructure(buf, t);
  	}

 	[DllExport("SumVector", CallingConvention = CallingConvention.StdCall)]
 	static float SumVector(IntPtr vec)
 	{
 		MyVector v = (MyVector)MarshalToStruct(vec, typeof(MyVector));
 		return v.x+v.y+v.z;
 	}

with:

dllimport final function float SumVector(Vector vec);

and:

exec function testdll()
{
	local TestManagedDLL dllTest;
	local PlayerController PC;
	local Vector v;
	v.X = 2;
	v.Y = 3;
	v.Z = 5;
	dllTest = new class'PFGame.TestManagedDLL';
	foreach WorldInfo.AllControllers(class'PlayerController',PC)
	{
		PC.ClientMessage(dllTest.SumVector(v));
	}
}

(outputs 10).


When passing a structure as an out parameter you can do the following, however I have not been able to get the whole strings inside structs thing to work without crashing and if someone figures out how, that would be an awesome addition to this. I am willing to bet the problem is nested structs are not being marshaled correctly and you will need to do a custom marshaling to get it to work properly (which means using IntPtr and other magic).

  	struct TestStruct
 	{
 		public int val;
 	}

 	[DllExport("OutTestStruct", CallingConvention = CallingConvention.StdCall)]
 	static void OutTestStruct(ref TestStruct testStruct)
 	{
 		testStruct.val = 7;
 	}

with:

dllimport final function OutTestStruct(out TestStruct test);

and your struct defined in UnrealScript like:

struct TestStruct
{
	var int val;
};

FINAL NOTE: This method may have serious drawbacks and limitations. One huge problem is that you risk leaking memory like the titanic. I am not sure how well everything is getting freed... I urge caution. I am merely providing a technical basis but it will be up to you to assume the risks of the implementation for your particular project. I take no responsibility for the use or misuse of this information for any reason whatsoever.

References:

Mastering Structs in C#
Getting Assembly Path


I hope this provides someone some assistance!


Starting a game in HTML5

Posted by , 08 June 2011 - - - - - - · 863 views

So recently I have become interested in HTML5 and the new Canvas tag from a development perspective. Browser adoption is starting to catch up to the standard (although Firefox's Canvas element is still slow compares to IE9 and Chrome which is a bit lame) and HTML5 is starting to look like an attractive game/simulation development option.

My plan is to build a top down, tile based game with A* pathfinding and smooth tile scrolling. I want it to have all mouse driven interactions (following the golden rule of casual development), simple vector based graphics (created in Inkscape), and simple and laid back game play.

Starting development in such an early technology can be a bit of a dark alley. Sure there are some enterprising developers creating some game libraries for HTML5 development (such as MelonJS) and some examples/tutorials on the subject, but over all the whole thing feels a bit mysterious.

My intention is to create my own simple game framework built directly on HTML5 without using an existing game library for HTML5 and without resorting to any conversion technologies. The idea behind this is that I am not making a game for the sake of creating a game, but for the sake of learning the technology of HTML5 for multiple potential applications.

My current progress has looked at how to structure the game and what sort of IDE to use to comfortably write HTML5 content. I have settled upon Netbeans 7 as my IDE of choice. It supports HTML5 editing and has all of the tools that I need. I simply created a php project and removed any files it generated/configured my ftp settings to automatically upload the files to my webserver. It allows me to remain organized in my coding!

The only external library I am using as of late is jQuery. This is simply too helpful to pass up as it really simplifies a great number of javascript tasks such as trying to include external js files in js files (I was looking for a way to do include style statements to make the code more manageable, but some structural changes needed to be made because the call is asynchronous).

Here is a wip shot from the current title screen that I am using for testing. The game centers around a smiley face (simple art assets) on a quest to gain happiness after losing the love of its life in an IM conversation.

Posted Image

Here is some of the very basic and potentially horrible html5 im using:

<!DOCTYPE html>
<html>
	<head>
    	<title>Journey of a Grin</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<link href="style.css" rel="stylesheet" type="text/css"> 
    	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
    	<script src="scripts/main.js"></script>
    	
	</head>
	<body onLoad="initGame('game')">
    	<h2>Journey of a Grin</h2>
    	<canvas id="game" width="800" height="600">
        	Unfortunately your browser does not support the HTML5 canvas element!
    	</canvas>
	</body>
</html>



Game updates: Title screen, menu, bug fixes

Posted by , in Game progress 12 February 2011 - - - - - - · 1,049 views
Game Maker, Progress, Updates and 1 more...
I thought I would post a quick blog entry to showcase the latest progress on my game: Attack of the Dapper Gerbils. It is a Game Maker 8 (LE compatible even though I have pro) game created as an example for my middle school students (and because I want to).

Here are some of the current screen-shots:

Attached Image
Attached Image

I really like the menu screen. I added some switches that get activated when the current entry is selected and some lights that illuminate to show the current choice. The entire thing is really over the top but that is perfectly fine.

Attached Image

To add to the over the top nature of the menu, I made it so that the MENU text "explodes" when enter is hit. This was accomplished using the following script in GML:

{
	if(!exploded)
	{
    	delta_x = x - bomb_obj.x;
    	delta_y = y - bomb_obj.y;
    	dist = power(delta_x,2) + power(delta_y,2);
    	bomb_force = 150000.0/dist;
    	vx = bomb_force * (delta_x/(abs(delta_x)+0.0));
    	vy = bomb_force * (delta_y/(abs(delta_y)+0.0));
    	exploded = 1;
	}
}

The distance between the two objects here is squared and by finding the "bomb_force" we are using a 1/r^2 force law. 150,000 in this case is just a "magic number" that gave an appropriate effect and is the result of constant absorption (Technically bomb_force in this case is more of an acceleration and the mass has been absorbed into the constant). I find a normalized vector (broken into components) between the bomb and the letters and then multiply this vector times the explosion. Also my code is setting this acceleration to the velocity x,y components but this is just taking advantage of the fact that the letters are for the most part stationary... I should probably adjust it to add to the vx and vy variables but I will do that when I get around to refactoring the code.

Attached Image

I like the wizard/mage guy here. I drew a really crude animation for him where his hands open and close and he blinks and moves his mouth. I want to make some ominous clouds roll in and then have him summon a zombie gerbil (a well dressed zombie gerbil).

Attached Image

In this update I removed my previous crudely drawn background in favor of a solid color. I find it less distracting.

Attached Image
Here we see the camera effect of centering on the door when the last orb is collected. This was accomplished using timelines in Game Maker.

Attached Image
Here I am riding on a cloud. To implement this I created a second x velocity component. When we are on a moving platform this velocity component is set to the velocity of the platform and when we are not on a moving platform this term is set to 0. Treating it this way allows us to still move around on top of the platform.

Want the source?

Get it here! If you want to use anything from it, please be my guest. You are welcome to use any of the "artwork" in the game. The music is all from Incomptech . The sounds were retrieved from the internet although I edited a few of them in Audacity to get more of the effect that I wanted. I do warn that the code is a bit of a mess.. I used scripts where I found it too tedious to use the visual action system but I did not use exclusively script because I wanted it to be relatable to my middle school students (I wanted them to be able to see the relation between what we were doing in the class and my game).

If you don't have game maker and you want a playble exe demo clicky.


Thank you for reading!


Faking It: Platform Game Ai

Posted by , 10 January 2011 - - - - - - · 1,792 views
neural networks, faking it, AI and 3 more...
Today's blog post is going to start talking about game AI for my untitled in progress game using Game Maker. I have come to the point in my game where I need to start making enemies that behave somewhat more intelligently than a sack of potatoes.

To start with I realized that there is a commonality between my player and the enemies when it comes to interacting with platform elements. Both the player and the enemies need to be able to respond to gravity and have similar interactions with platforms in the game. Furthermore all enemies regardless of type will also need this behavior. The approach in some languages might be to create an "entity" class and have both the player and all entities inherit from this base class. I decided though that this might be a bit of overkill (after all while enemies and the player are similar, they are also very different) so instead I am opting to create a set of common routines to check platform collisions to share between the player and enemies. I am also creating a base enemy class which all enemies will use as a parent (Game Maker uses the term Parent, but this is the same concept as inheritance in other languages).

Here is check_platform_collision:

{
	test_obj = argument0;
	return collision_rectangle(test_obj.x + test_obj.sprite_width/4,
   	argument1+test_obj.sprite_height+(argument2-1),test_obj.x + (test_obj.sprite_width*0.75),argument1+test_obj.sprite_height+argument2,platform_base,false,true);
}

and check_platform:

{
	test_obj = argument0;
	temp_y = test_obj.y;
	col_id = check_platform_collision(test_obj,temp_y,1);
	
	if(col_id >= 0 && test_obj.vy > 0)
	{
    	test_obj.vy = 0;
    	while(check_platform_collision(test_obj,temp_y,-1)>=0)
    	{
        	temp_y = temp_y - 1;  
    	}
    	test_obj.jump = 0;
	}
	
	return temp_y;
}

Basically the code is simply to return the new y coordinate of the player after the collision checking is done. I am still working on writing a common routine for ladder collisions which currently is duplicated and looks like this:

	col2_id = collision_rectangle(x,y,x+sprite_width,y+1,ladder_bottom_obj,false,true);
	if(col2_id >=0 && climb)
	{
    	climb = false;
    	ypos = ypos -2;
	}

So we currently have a base enemy "object" and an enemy type that inherits from that base called gerbil. In my game the enemies are going to be gerbils with top hats... Currently though I have an ugly stand in programmer graphic of a box.


Attached Image

Alright so I have set the stage for how I am creating a base enemy to start programming my AI with. I have a common set of routines between my hero and enemies to not repeat code and I am inheriting from my enemy base class for all enemy types.

But what AI do I use??

The heart of the question now is HOW do I add enemy AI. For my player the logic goes that I respond to player interaction and adjust variables (in my case vector velocity components... fancy math speak for saying I take my velocity vector as represented by vx and vy variables, performing euler integration by adding acceleration to my velocity and then adding my velocity to my position... Or even simpler I made a platform engine type thingy).

If I was creating a networked game then I could create custom events that are triggered instead of direct user interaction and then create a queue of "actions" much like you would do in a time management game... So my enemies could do the same and I could call events that move the character instead of responding to input! but then I am left with the problem of when do I call these events? Is it worth doing this or is direct manipulation of the variables a more valid approach? Both have advantages and the designer is left to answer such questions.. I am going to experiment with the user defined events in Game maker that are called, and then my scheme must call these events to cause the enemy to move. The logic is then to "control" the enemy in much the same way the player is being controlled by the player.

Neural Networks and Genetic Algorithms!

So we need to do AI and anyone who has a casual interest in the subject but no real experience with actually making a game, might be inclined to say something along the lines of "I will use a neural network, fuzzy logic, and genetic algorithms for my game!" which is really a pointless combination of buzzwords designed to make anyone who says it seem somewhat intelligent.

The problem with this approach is beyond being utterly complicated it will not yield a fun and playable AI. The real way that most if not all game AI is done is by finite state machines which sound like some really complex and abstract concept! Let's quickly create a state class and a bunch of other fun states to be inherited from it and then use a dynamic array to manage all of our fun states! and then let's create a state transition table and do all sorts of fun stuff while we try to figure out how we actually "use" this mess we just created!

Or... perhaps not. In my mind the main approach to take when creating an AI in this situation is to layer behaviors. What I mean is that I am going to create a combination of behaviors and responses to conditions that the enemy can encounter and by crafting enough responses to enough conditions I will eventually arrive at something that looks intelligent. This can be comfortably done using various if/else statements and there is no real reason with proper abstraction to do more unless your creating a massive project.

I can also choose to perform certain behaviors are random intervals... but probably not COMPLETELY random intervals. Everything when it comes to such behaviors is best talked about in terms of weighted probabilities. For instance the probability of my next action to be continuing to type this blog post is higher than the probability of my next action to be to break out in an elaborate dance routine. To implement this we can use a random number generator that provides equal weight to each numerical outcome and then look for various ranges of values when we check to see which state to use.

State in this case is not really referring to an object (although I am sure people will disagree, we must make simplifications sometimes) but an abstract concept... State is the current values of all variables in the enemy object and to transition states is to change one or more variables to cause some new action (changing our x velocity to go right instead of left, or zeroing out the velocity to stop.). State transitions are the if statements that govern which enemy states to use.

The rules from transitioning to one state for another are either going to be based on random events or based on met conditions (such as the enemy is in range of the player).

Also I am going to introduce some variables to the enemy to represent certain physical properties. For instance I could have a variable indicating the enemies stamina. If the stamina gets too low then the enemy will go to a resting state. Once the stamina is regained then we can choose to perform a random weighted state transition OR if the enemy is close we can attack, ect.

The next blog post I write is going to talk about how I go about implementing these concepts in my game. I am currently working on routines to check if an enemy is about to leave a platform, if an enemy is over a ladder, and other routines to gain information about the game level. This will allow me to implement a form of steering behaviors for my enemies as well.

Thank you for reading!


The New Gamedev And Slew Of Journals

Posted by , 09 January 2011 - - - - - - · 494 views
New GDNet, mixed blessing and 2 more...
Hello everyone, I woke up this morning to see snow and the brand new GameDev.net site! The entire site is taking me some time to get familiar with and I am still trying to get to grips with the updated user ratings.

It appears as if all GameDev users have blogs... which may be a mixed blessing. I appreciate the fact that giving everyone the opportunity to post a blog will perhaps provide new content and more interesting articles to read, potentially by people who did not have a subscription to GameDev in the past, however I really do wish that people would put more thought into their posts.

Today I actually saw a journal entry containing the word "ok"! I am not singling out a particular user, however such entries will eventually diminish the value of the developer journals... It is not that I think every entry is going to be a sentence, but if every new user decides to experiment with the fact they have a blog then we could quickly see a lot of first blog posts... Before this would not have been an issue due to the relative small subset of users subscribing to GameDev, but now it could completely dominate all of the latest journal posts. I for one have found the journals in the past to be filled with wonderful information... and I think paying monthly for a journal helped to keep the journals in the realm of people interested in actually posting meaningful content (I did not purchase a GameDev subscription until having been around the forums for a number of years for instance).

On the other hand there could be an increase in the number of good journal entries now that there is an increased number of journals and I definitely look forward to reading those!

I guess time will tell... maybe everyone just wanted to post a journal entry to try it out and eventually things will become more "normal". Potential fixes if it does become a problem might be to create a minimum word count for an entry!

One feature I am liking of the new journal system is the ability to attach files to my entries. This will hopefully enable me to share files with you all (such as the source in my last journal entry) without having to worry about bandwidth issues. I am also looking forward to playing around with the formatting options for the journal entries and the themes. I do wish the long title of my journal didn't appear broken under FireFox... For now I am going to leave it alone and maybe it is just a bug that needs to be fixed (the journal title was fine under the old GameDev).

Thank you for reading. My next journal entry is going to cover AI for my side scrolling platform game. In the mean time I hope everyone has fun exploring what the new GameDev.net has to offer!


Going backwards - Digital adventures of the second dimension

Posted by , 06 January 2011 - - - - - - · 503 views

Introduction

Hello! It has been a long time since my last journal entry here on GameDev. I have been extremely busy, but I hope everyone has had a great Christmas/New Year/Other Holidays!

Newton's Enigma is still under active development. I recently downloaded the December UDK and I am excited to begin playing around with some of the new features.

Today's post is going to focus on a different project of mine. As part of my research project I happen to work with middle school students in order to teach them game creation. We accomplish this task by using the Game Maker program by YoYo games. The challenge that we present to the middle school students is during a school year they are to develop their very own Game Maker game in teams after having been taught basic game design/programming concepts.

While I have game development experience in other languages, and Game Maker experience, I have never developed a full game in Game Maker. I decided that if I was to ask my students to create a game in Game Maker, I must create a game of my own. In my mind confidence in an instructors abilities must be demonstrated and not assumed.

The project

So I decided that I needed a game project to develop and I settled on creating a generic two dimensional side scrolling platform game. This type of game demonstrates a number of valuable concepts such as scrolling, enemy AI, and variables without a lot of other potentially more complicated issues such as layering and coordinate transformations (which would be present in top down/isometric perspectives).

The goal is to create the entire set of graphics, animations, and programming code (in game maker) myself. I am using royalty free music and sound effects from the internet (properly credited) because such things are beyond my scope of both time and experience.

I am a huge fan of Dos games such as Commander Keen, and Hocus Pocus, and so I decided that I would like to involve some similar elements but under my own style. In terms of design principles the entire game is to be made up as I go along but I want the game to grow organically. What this means is that every feature is to be heavily tested and prototypes and nothing is to be added for the sake of adding it, but because it is directly needed by the game. For instance I would not add springs soley because another game has springs. I would only add such elements if I had a level or a design that required them.

The game is designed and created in Game Maker 8 Pro, using the sprite editor for all graphics and designed with a 320x240 view.

Screen-shots







Scripts

When possible the Game Maker visual scripting system is being used for the game. However there are some situations in which this system becomes unwieldy to use. In this situation we make use of the GML script ability.

One script that was written was to display helpful messages to the user. This piece of script is draw_info_box.


{
sign_x = argument0;
sign_y = argument1;
sign_txt = argument2;

draw_set_font(argument3);
draw_set_halign(fa_center);

border_size = 2;
sign_width = string_width(sign_txt) + border_size * 2;
sign_height = string_height(sign_txt) + border_size * 2;

draw_set_color(c_white);
draw_rectangle(sign_x - sign_width / 2,sign_y,sign_x + sign_width/2, sign_y + sign_height,false);
draw_set_color(c_black);
draw_rectangle(sign_x - sign_width/2 ,sign_y,sign_x + sign_width/2, sign_y + sign_height, true);

draw_text(sign_x + border_size ,sign_y + border_size, sign_txt);

}







Another script that was used is when it comes to getting the player out of a platform. We check for collision with a platform base (making use of the parent system of Game Maker which is a lot like Inheritance in other languages) and we move the player up a pixel until we are no longer overlapping the platform.


{
ypos = y;
col_id = collision_rectangle(x + sprite_width/4,y+sprite_height,x + (sprite_width*0.75),y+sprite_height+1,platform_base,false,true);
if(col_id >= 0 && vy > 0)
{
vy = 0;
while(collision_rectangle(x + sprite_width/4,ypos+sprite_height-2,x + (sprite_width*0.75),ypos+sprite_height-2,platform_base,false,true)>=0)
{
ypos = ypos -1;
}
jump = 0;
}

col2_id = collision_rectangle(x,y,x+sprite_width,y+1,ladder_bottom_obj,false,true);
if(col2_id >=0 && climb)
{
climb = false;
ypos = ypos -2;
}
y = ypos;

if(x+vx < 0 || x+sprite_width + vx > room_width)
{
vx = 0;
}
}







The Orb count is dynamically drawn like so:


{
if(object_exists(orb_obj))
{
draw_set_color(c_black);
x1 = view_xview[0] + view_wview[0] - 20;
y1 = view_yview[0] +2;
orb_txt = string(orb_cnt-instance_number(orb_obj))+'/'+string(orb_cnt);
draw_roundrect(x1-1,y1-1,x1+string_width(orb_txt)+1,y1+string_height(orb_txt)+1,false);
draw_set_color(c_purple);
draw_roundrect(x1-1,y1-1,x1+string_width(orb_txt)+1,y1+string_height(orb_txt)+1,true);
draw_set_color(c_white);
if(orb_cnt - instance_number(orb_obj) == orb_cnt)
{
draw_set_color(c_yellow);
}
draw_text(x1,y1, orb_txt);
}
}







The orbs above the door rotate around and increase every time an orb is collected. This is also done using a script:


{
total_orbs = hero_obj.orb_cnt-instance_number(orb_obj);
orb_ang = 0;
if(total_orbs > 0)
{
orb_ang = 360.0 / total_orbs;
}

for(orbIdx = 0 ; orbIdx < total_orbs;orbIdx+=1)
{
orb_x = x +8+cos((rotate+orbIdx*orb_ang)*(3.14159/180))*20;
orb_y = y - 20- sin((rotate+orbIdx*orb_ang)*(3.14159/180))*6;
draw_sprite(orb,-1,orb_x,orb_y);
}
}





What I have learned so far

One thing that I have been enjoying about this project is the fun of creating a random game. It is nice to create a game in a stress free manner and my game development experience in other languages/technologies has helped me make good use of Game Maker features. I also feel more confident in my ability to use the Game Maker technology to teach Game Programming.

While the game is still under development, you are all welcome to download the full Game Maker 8 Pro files and a demo exe from my website: CGame Demo.

My only restriction on using the file is that if you use anything from it, please credit me for the use. You are welcome to use the graphics, borrow pieces of the code, or whatever you would like to do, so long as I get a mention. The graphics are not great but I know that even programmer art can be difficult to come by.

Thank you for reading!


Updates

Posted by , 04 April 2010 - - - - - - · 356 views



This is a screenshot from a demo level I made using UDK for a symposium I recently attended. The purpose of this level was to build my skills in the level editor program, to experiment with a modded HUD, and to learn Kismet/Matinee.

The picture to the left of the image is a model I have previously shown that was created in Blender. The doors to the right have a logo of my school's mascot on the doors.



As I approach the doors, the doors open. This was done using two triggers placed on in front of the doors. If I overlap the trigger, I have a kismet script that plays a matinee animation to open the doors. For the animation the first frame is the doors closed, and the second frame is the doors open. This animation is composed of two separate movement tracks for the right and left doors respectively.



For this level I wanted to experiment with an outdoor scene, and specifically I wanted to be able to transition from an interior level to an exterior scene. I did not want it to be obvious that this level had an outside component and so I hid the only escape to the outside level behind a machine that I can move out of the way with the physics "manipulator" (a.k.a gun).



I also wanted to experiment with the vehicle system and terrain and so I combined those two things together in order to play around with vehicles driving around. I wanted to also play with speedtree as well, but I ran out of time before the symposium.



To the far left is the start of a spiral staircase which leads to the second floor. Straight ahead is a switch on the wall that when triggered causes a UI scene to be displayed (just an image).



Here we are going up the spiral staircase to the second floor. It was a real pain to get the number of steps/radius correct! and then building up the second floor geometry took a while.



We can manipulate these objects with the gravity manipulator.



More manipulations of the physics objects.



This is a shot of the editor and what the building looks like on the outside when you leave the building and enter a vehicle.

From here the next steps are to add more "manipulators" for finding the distance between objects and other data, add a journal for recording information about the world, and start testing ideas for some demonstrations. I also would like to display the forces acting on physics objects, and I would like to modify the vehicles so they do not fire projectiles.






December 2016 »

S M T W T F S
    123
4 5 678910
11121314151617
18192021222324
25262728293031