Category: development

Ludum Dare 23 postmortem

Is it supposed to be ironic and funny that they call these things post-mortems? What died?

My mind rebelled when they announced the theme Tiny World. There was another theme that I’d hoped would win, because I’d recently had an idea to do a game like that one. But it didn’t.

Friday night I was hanging out (more…)

Tutorial: Building a Game Maker Extension

[Update 1/13/2014: See the official GameMaker documentation and this MSDN blog entry for how to build GM Extensions directly inside of GM:Studio. The GM Extension Builder tool that I explain how to use in this article will build GEX that can work with GM 7, 8, 8.1, and GM:Studio. As long as the GML used in the extension is compatible with the version of GameMaker that the extension is added to, the extension should work. ]

One of the nice things about Game Maker is that it is extensible. Developers can make their code more re-usable by converting their GML scripts to Game Maker Extensions. Once the .gml code is packaged in a .gex extension, you can import the extension into Game Maker and use the functions it provides in any project with ease. This means over time you can build up an entire library of re-usable functions that you can bring into your projects, saving you time and allowing you to focus on building new stuff instead of re-implementing the same basic things again and again. (more…)

Notacon 9 Game Maker: Crash Course presentation materials for your consumption

Game Maker: Crash Course materials are online, open to the public on Google Docs.

Here’s what you get:

Presentation slides. Be sure to read the notes, there is actual information. More than would fit into the talk itself!

Space Invaders Kit. All you need is Game Maker installed and you can build it yourself! A great way to get started. Includes:

  • starter project file,
  • final project file,
  • final project .exe build,
  • sprite images,
  • sound files.
  • step-by-step instructions for how to do it!
  • project specification document — a good way to start out any project is to document what you want it to be. Follow this as a template for your own designs!

MUST!GET!EGG!

Inspiration strikes in unexpected ways sometimes. This morning while I was listening to the news on the local NPR affiliate, a story came on about an easter egg hunt in Colorado that was canceled this year because the year before, parents were out of control, being aggressive about making sure their precious child got an egg before they were all snatched away by the villainous other children.

I was so appalled by the story that I made the following snarky quip on Facebook:

MUST!GET!EGG! genesis

The imagery was so strong that I knew I just had to work up the idea into a full concept and design, and then build a game. I wrote up a little design document today and I liked it, so I put in a few hours this evening working on it, and it’s still very early but I think this will actually be a decent game when it’s all done, if I can make everything work the way I want it to.

So far it’s very crude, but in less than four hours I had playable characters roughed out. Here’s the shotgun-toting Hunter in action:

MUST!GET!EGG! alpha screenshot

One thing I noticed about this creative process is how satisfying it is to have an angry reaction to a news story and turn it into the inspiration for a creative work. This is how I know that I’m a game designer: when my first response to something is “Make a game out of that.” Doing it in response to something that makes me feel is what makes me an artist.

I also found the game concept itself very satisfying because it’s so inappropriate — it’s hard to get much wronger than having shotgun-toting hunters gunning for bad parents at an easter egg hunt to teach everyone a lesson. If this were done up as anything but a zany pixel-art graphics 2D game, it’d probably be disturbing and controversial. As it is, I suppose in the next few weeks or months if it gets noticed, it may end up generating some controversy, especially if the news media picks up the story of this game as sortof an echo of the original story.

The thing that makes me happy about this project is just how quickly I can work when I have a spark of creativity. My Game Maker craftsmanship continues to improve and I find that I can make things very quickly, which is essential for me. Unlike the experience I had with the Global Game Jam back in January — which was amazing in its own right — tonight I didn’t have to go through the agony of losing work due to a corrupted project file, and having to rebuild everything. I worked quickly, and got results quickly. I can imagine completing a full project like this in maybe <100 hours, which is fantastic.

Every time I pick up Game Maker and build something with it, I get a little more confident, find it a little easier, and learn a little more. It feels great.

Wrapping safe zone spawn in Game Maker

I got a working demo of a safe zone spawn which works with wrapping rooms. I refined my technique for determining the safe zone, and now instead of being a square, it is circular.

I like this approach, it works pretty well. Basically, rather than trying to literally “wrap” the safe zone around the edge of the room, I create five safe zones. They are at protected(x,y), protected((x+/-room_width), y), and protected(x,(y+/-room_height)). In my instance_create loop, I merely determine whether the new instance’s candidate x,y location is within some distance of any of these five points.

The current script I wrote up is working, but it just uses a distance in pixels. My original approach calculated a distance automatically, based on the size of the objects’ sprites, and a padding factor, which I liked. I’ll likely create a version of this script that works that way in the next day or so, when I have a moment, and then package the whole thing up into a .gex for distribution.

Until then, the .gmk source is already up on the site.

One other note: One of the annoying things about Game Maker is that when you write a function, you can only return a single value. In most other languages, you can create classes of objects, which can be used to encapsulate as many values as you like, and return the entire object. Game Maker kindof lets you do this, but you have to create a Game Maker object, which it a bit more literally object-like, in that it carries some baggage with it. I think that my function would be more useful if it simply returned a set of (x,y) coordinates without actually creating an instance there. But I can’t return both x and y — a function can only return one value. I could return the id of an instance of an object, however, and simply spawn an empty, spriteless object at those x,y coordinates, and allow the developer to either change that instance into whatever kind of object they needed there, or else grab the x and y values from the object and destroy it. It’s an idea I’m toying with, not really sure which way to handle it is best at the moment, but it’s fun to play around with ideas.

Spawning objects outside of a safe zone in Game Maker

In Game Maker, it’s non-trivial to spawn a new instance, avoiding collisions with existing objects in the game. This can make it tricky to create games with “fair spawning” so that the player isn’t automatically killed when a new, randomly-placed instance springs into existence.

It isn’t terribly complicated to work around this problem, thankfully. Basically, the approach I take is, knowing the x,y coordinates of the instance or object that you want to want to avoid collision with, and the size of that object’s sprite, you can define a “safe zone” around the instance you wish to protect.

I’ve whipped up a quick demo in Game Maker 8, showing a technique which seems to work pretty well. This is a very simple illustration of the approach, and could be refined further to handle wrapping the safe zone around the edge of a room, or to handle enemies of randomly varying sizes. To make it easier to understand, I’ve actually created an object to represent the “SafeZone” . This is unnecessary, as the dimensions involved can simply be calculated on the fly, using the right GML.

Source .gmk.

Notacon 8 Presentation video now online!

Notacon blog announcement

YouTube

Boobie Teeth alpha downloads

Packt Press announces Game Maker 8 Cookbook

http://www.packtpub.com/game-maker-8-cookbook/book

I am contributing to this book as a technical reviewer, and it’s my first time getting credit in a publication, so I’m kindof excited and happy about that.

[Update 1/11/2013: After several months of delays, I have heard from the publisher that this book is about to be canceled. However, I am now working on reviewing a book on GameMaker: Studio from the same publisher, which looks like it’ll be a much better book.]

“Cannibalistic” AI Targeting for Game Maker 8

I’ve made an improved version of my 2D AI Targeting demo for Game Maker. My original AI Targeting was limited by the fact that an object could not target other instances of the same object type — doing so in effect would cause the seeker object to attempt to target itself.

The original AI Targeting routine used instance_nearest(), which works great if you are targeting an object of a different type. If you need to target the same type of object, however, instance_nearest() won’t help you, since the nearest instance of the same object is always self.

Using instance_nearest_extended by Kyle_Solo, I was able to come up with a routine that allows for “cannibal” AI targeting — that is, targeting an object of the same type as the seeker.

I struggled for a long time to use the instance_xth_nearest() method to accomplish cannibal targeting, which seemed to be suitable as it has a built-in criteria test, but was unable to get the function to work as desired. I’m still not entirely sure why, but I am guessing that it may be due to the “other” keyword being undefined or referencing “noone” when an object is not involved in a collision.

I ended up successfully completing the project using instance_nth_nearest and a bit of extra code which performed the criteria testing that I required. In order to get my testing code to work, I had to introduce a global variable to count the number of instances of the targeted object, so I could construct a loop to iterate over them using instance_xth_nearest(). I’m wondering if there isn’t a faster or more graceful way to accomplish this, but it works well for now.

In the video above, the Arrows target the nearest Arrow that is small enough for them to “beat”. The rule I am using here is that a bigger arrow must be 1.3x the size of a smaller arrow in order to be able to “beat” it, but this could be modified to some other condition by changing the can_beat() function. If a candidate target cannot be “beaten” the arrow considers the next nearest arrow, and so on, until all of the instances of the targeted object type have been checked. If no arrow is small enough to be “beaten”, the arrow flies in a straight direction.

Source .gml and a demo .gmk project is available at the Releases page; a .gex extension build will be released in the near future.

AutoFullScreen 1.1

After releasing my AutoFullScreen 1.0 extension for Game Maker, I noticed a minor bug with the way small rooms were being scaled up to fill the window.

When scaling up a small room, in 1.0 the scale factor is calculated by determining whether the room was taller or wider, and used whichever was the longer dimension along with the display’s corresponding dimension to calculate the scale ratio. This was close to correct, but not quite right.

In 1.1, the scale factor is calculated both ways, using the height and the width, and then use the smaller of the two room:display ratios rather than the larger of the two room dimensions. The difference is subtle, but the upshot of this is that if you try to scale up a 4:3 room on a 16:10 display using the 1.0 method, it fills the screen completely, distorting the dimensions of the room. In 1.1 the room does not get distorted, as intended.

I have fixed the bug and added a feature to the function to make the zoom function optional. If you prefer to have the room drawn at actual size, you now have that option.

The new version is up on Releases.