Category: development

Cleveland Game Developers Level Up 2/20/16 workshop

Excuse to Create – West Side – featuring “Level Up”

Saturday, Feb 20, 2016, 1:00 PM

Lakewood Public Library Main Branch
15425 Detroit Avenue Lakewood, OH

14 Video Game Developers Went

About Excuse to Create”Excuse To Create” is our casual working meetup event. Want to brainstorm or ask questions of other developers? Want to turn up your headphones and code without family distractions? Maybe look for opportunities to collaborate, pair-program or share your latest prototype? Just want to draw, sketch, or compose? This is the meet…

Check out this Meetup →

Global Game Jam 2016

Once again, this Friday I’ll be joining with my fellow Cleveland Game Developers friends to participate in the 2016 Global Game Jam. I’m looking forward to hearing what the theme will be this year, and seeing all the games the different groups at the Shaker Heights location will create. Special thanks to Launch House for hosting us again this year!

iMprOVE_WRAP extension for GameMaker Studio

Today I’ve released a new asset on the YoYoGames Marketplace, called iMprOVE_WRAP.

Many video games have the feature that exiting one side of the screen will “wrap” you around to the opposite side — notable examples of this include the smash hit classics Asteroids and Pac Man. GameMaker: Studio has a GML function, move_wrap(), which is intended to provide this feature easily, but it has a few limitations. iMprOVE_WRAP addresses these limitations, resulting in a more powerful, flexible implementation.

iMprOVE_WRAP improvements over move_wrap()

Wrap behavior is no longer based on the built-in GML speed variables.

One of the most troublesome limitations of move_wrap() is that it only works for instances that have a speed. In standard GML, the variables speed, hspeed, and vspeed are used to move instances. But you can also “move” an instance by changing it’s x and y position in the room, without setting a speed. Many GM:S users will implement their own movement systems that eschew these variables, in order to give themselves complete control over the movement engine. When they do so, they are often confused when they discover that move_wrap() doesn’t do what they expect.

iMprOVE_WRAP eliminates this dependency, so that an instance no longer need to use the GML speed variables in order to wrap; wrap behavior in iMprOVE_WRAP is based entirely on an instance’s x,y position.

iMprOVE_WRAP_animation

Wrap region no longer limited to room borders

Another problem with move_wrap() is that it is intended to work with the Outside Room or Intersect Boundary GML Events. This means that move_wrap() is only useful when an instance moves outside the room, or encounters the edge of a room. But in many games, the “play field” may not be synonymous with the entire room — the room might have a border, or “dashboard” or “heads up display” which ideally should be considered “out of bounds” with regard to the play field.

iMprOVE_WRAP allows you to define a “wrap region” — a rectangular area inside the room, which instances wrap around the borders of, rather than the borders of the room.

Independent horizontal, vertical margins

With move_wrap() the margin argument which determines the margin by which the instance must be outside of the room is the same for both horizontal and vertical travel; with iMprOVE_WRAP the horizontal and vertical margins may be set independently of each other.

Wrapping instances can (optionally) draw themselves on both sides of the border

With move_wrap(), an instance still draws its sprite in the default draw in only one location: at (x,y). If the instance is off the edge of the wrap boundary, but hasn’t yet crossed over, the instance draws on the “pre-wrap” side of the room; after the instance progresses by margin pixels over the border, then the instance’s position is moved over to the “post-wrap” side of the room, and the instance is drawn there. This is not a big deal if the instance crosses the wrap boundary quickly, and has a relatively small sprite; but for slower-moving instances, or instances with larger sprites, it creates a jarring “jump” effect, where suddenly the instance appears on the “post-wrap” side of the boundary, with no real warning, rather than gradually entering the room.

iMprOVE_WRAP solves this by providing a new function, iw_draw_self_wrap(). This new function augments the default draw by drawing the calling instance four additional times, at positions left, right, up, and down from the actual instance, the width or height of the wrap region away from the actual instance. Thus, when your wrapping instance is moving off the edge of the wrap region, one of these extra drawings is poking out on the opposite side, creating an illusion of continuity as the instance leaves one side and emerges from the other.

For a wrap region that is smaller than the room itself, it’s best to do your drawing on a surface that is sized to the area of the wrap region; otherwise the parts of the drawing that should be outside of the region will be visible outside of the wrap region. Alternately, if drawing to a surface is not something you want to do, you can “mask off” the portions of the room outside of the wrap region by layering objects at a higher depth around the border, like a picture frame or dashboard.

Collision detection on both edges of the border

To compliment the iw_draw_self_wrap() function, I’ve added a new collision function, iw_collision_wrap(). This function checks for collisions at the four places occupied by the four drawings drawn by iw_draw_self_wrap(). There are actually two iw_collision_wrap() functions.

The more basic, iw_collision_wrap() sets five instance variables in the calling instance to store the id of any instance in collision: other_center, other_up, other_down, other_left, and other_right.

The more advanced, iw_collision_wrap_map(), returns the id of a ds_map, which holds those same five instance variables as keys, which you can access using ds_map_find_value().

Which to use is up to you, and the style of programming you prefer. iw_collision_wrap() is easier to use, and if you don’t mind the instance variable names, is probably slightly faster at runtime. iw_collision_wrap_map() is for programmers who get pedantic about “correctness” and want their functions to return something, not cause side effects in the application state. Since it’s not possible in GML to have a function return 5 separate values, we return a data structure that stores the five values. The downside of this is that you have some overhead, namely a need to clean up the ds_map when it is no longer needed. Fortunately, it’s not hard. The example project will demonstrate how to do this properly, so don’t worry.

iMprOVE_WRAP is available at the YoYoGames Marketplace for $2.99; however I am making it free for the first 10 downloads. Please rate it and review it if you give it a try!

Get iMprOVE_WRAP

scrollsnap extension for GameMaker: Studio

My latest GameMaker extension, scrollsnap, is published!

Asset listing at the YoYoGames Marketplace

Documentation

Demo video:

What’s scrollsnap?

Scrollsnap is a way of setting up a View in your room so that it “snaps” to the next screen’s worth of space when the followed instance moves outside the view. Simply put, it’s a view that stays put, but if you walk off the edge of the view, the view updates, giving the appearance that you walked off the edge of one screen and on to another.

Old-school video games such as Adventure, Pitfall!, and Berzerk used this approach to provide a larger game world to explore and play in, before programmers figured out how to make the hardware support scrolling.

Thinking about a human-like AI for playing Scrabble

[I got into playing Words With Friends on Facebook and my mobile phone back in 2012, and started writing a lengthy article on designing an AI to play scrabble-like games in a manner that convincingly simulates a learning human. This weekend, several years later, I’m a spectator at a local Scrabble tournament, and decided to finally finish up my thoughts.]

Designing AI for Scrabble-like games

I’ve been playing the Zynga game Words with Friends with various people for a few weeks, and have gotten progressively better at the game. After looking back and reflecting on the evolution of my play, and the development of my strategy, I became inspired by the idea of a convincingly human-like AI that embodied the various stages of my development as a player.

While actually programming it is a little more effort than I want to put into it, even just thinking about the design for such an AI is interesting.

(more…)

What I love and hate about game jams

This weekend was the weekend of Global Game Jam 2015. All over the planet, more than 10,000 participants got to try their hand at making a game in 48 hours, on the theme “What do we do now?”

I thought about the theme, and tried to imagine a situation that would lead someone to say, “What do we do now?” and the first think that came to mind was being stranded. Quickly, I envisioned a space ship that encounters a systems failure while in transit, and becomes disabled in deep space, with the crew left to figure out what to do to get things back working again. (more…)

Global Game Jam 2015 Warmup

On 1/23/2015, Global Game Jam weekend will be kicking off. I will be working at the Cleveland Game Developers site at the LaunchHouse in Shaker, OH.

This Saturday, 1/17, I will be leading a Pre-Jam Warmup session to give our participants opportunity to limber up their creative and technical skills. It’s a good idea, and fun. The goal is to build confidence and ensure readiness for the big Jam coming up the next week.

If you want to do your own version of this wherever you are, here’s what we’ll be doing for our warmup sprints:

WARMUP SPRINTS

00: SYSTEMS CHECK — ALL SYSTEMS GO!

  1. Launch your tools and make sure they still work.
  2. Check for updates, download and install any (if you wish).
  3. Test to your satisfaction that your stuff is working (write a “hello world” and prove it’s all working properly.)
  4. Create/Verify you can log into your GGJ account, any other accounts you may wish to use during GGJ15 (Trello, GitHub, DropBox, itch.io, newgrounds, kongregate, etc.) If you’re new to any of these, you’ll want to take time during the week leading up to the Jam to familiarize yourself with them.
  5. Create a checklist of things to bring to the Jam, and get everything together ahead of time
    1. Computer
    2. Verify you can connect to wifi at your jam site
    3. Create/verify you can log into any web accounts you plan to use during the Jam
      1. globalgamejam.org – be sure to join to your local site
      2. dropbox.com
      3. trello.com
      4. github
      5. itch.io
      6. kongregate
      7. newgrounds
      8. Make sure your team members can access any shared resources or services too!
    4. Power cables, extension cords, surge bars
    5. Peripherals
      1. headphones
      2. gamepad controller
      3. mouse
      4. 2nd monitor
      5. image scanner
      6. musical devices
      7. ???
    6. Human comfort
      1. Food/drink
      2. Pillow/sleeping bag/blanket
      3. ???

We’ll run this one up to an hour, but as soon as everyone’s done, we’ll proceed to the next sprint. If you’re downloading something huge and it’ll take longer than an hour, try to complete this before 1/23/15.

01: Development exercise: Asteroids

Asteroids is a simple action game. If you’ve never heard of Asteroids, google it and watch a youtube video or two, and you’ll get the idea in a few seconds. You’ll understand it faster than I can explain it in words.

Your job is to see how much of it you can build in an hour. You can make your own interpretation of the game, or try to slavishly re-create the original in every detail, it’s up to you. Work independently or as a team (if you have a team). We’re all in this together, so if you run into trouble, ask the room and someone will chime in with advice.

If you finish early, polish for the remainder of the hour, innovate a new feature, or whatever.

At the end of the hour, we’ll take a little time to show off our work and talk about what went well/what could have gone better.

02: Development exercise: Simple 2D platform engine

Take 1 hr to Work up a simple, 2D platform engine from scratch.

You don’t have to spend any time on animating sprites unless that’s something you *want* to focus on as a graphics contributor; square and rectangle programmer art representing the hitbox of your game objects are perfectly fine.

You decide how you want it to work in detail, and implement it however you like. The goal shouldn’t be to try to complete all of these features in an hour, but to choose a few of them and make a solid, well-crafted engine out of them — quickly.

You can design your own requirements, or use the following checklist of features and pick which ones you wish to support in your engine:

  1. solid platform
  2. jump-through platform
  3. destructible platform
  4. movable platform (player can pick up or push)
  5. gravity
  6. walking
  7. running
  8. shooting
  9. jumping
  10. wall walking
  11. ceiling walking
  12. double jump
  13. wall jump
  14. player health/death
  15. static enemy (spikes)
  16. moving enemy
  17. scrolling/camera
  18. moving platforms : any or all of horizontal, vertical, swinging, circle
  19. ladders
  20. pickup item (coin, power-up, etc.)
  21. door (how the door works is completely up to you.)

After an hour of development, we’ll spend an hour on demo and code review so we can learn from each other’s work. The code review is not meant to be exhaustive, but to show off highlights in technique if you found a cool way to do something, or to ask for ideas for how to do something better that you struggled with.

03 – Free for all

If we still have energy and want to keep going, we can come up with more ideas for sprints and ad lib it as we go. Maybe a graphics-oriented sprint, or sound effects engineering session, or a concept/design session where you have to brainstorm a pitch to a randomly chosen theme. We can quickly discuss and vote on it as a group.

XX – Wrap-up:

By now, even those of use who have never met or attended the meetup before will know each other a little bit, and will have worked together. Now’s a good time to talk to each other and find out if you have the right mix of talent and interest to maybe team up next week. This can go on as long as it needs to.

Color Is Everything: a Ludum Dare 31 Post-Mortem

Originally published here.

Play Color Is Everything

Preconceived notions

Going into this weekend, I knew I wanted to make a game that would serve as a statement about the intolerable state of civil rights in the present-day United States. It seems like almost every day there’s another story about police using excessive and all too often deadly force, often unnecessarily or for very little provocation. We live today in a police state where citizens rights are routinely denied, due process and the right to a fair and speedy trial have been forgotten, and out government doesn’t merely seem unwilling or incapable of doing anything about it, it refuses to do anything about and then punishes those who speak out and demand it — as evidenced by a mockery of a Grand Jury investigation into the police shooting of an unarmed 18 year old named Michael Brown in Ferguson, Missouri, last month, and a 12 year old boy in my home town of Cleveland, Ohio that happened just as the news hit that there would be no trial in the Michael Brown shooting incident. No trial, and then force used to break up peaceful demonstrations which turned them into riots.

One of the finalist themes was Color Is Everything, and I thought that would work perfectly if it was chosen, but for some reason I didn’t expect it to — I just never feel that lucky, I guess. So I looked at the other themes and considered how I might fit my protest statement into a game that satisfied the other themes, and I thought that I could use “Entire game on one screen” if it came up, but I never expected that it would. When it did, I was surprised, but happy because out of all the other themes it was the one that afforded the most freedom of game concept, so long as I could fit everything on one screen.

Design

In designing the game, I focused almost exclusively on the message that I wanted to send, and the actual game play was secondary. I wish I could have spent more time on refining the game, because as it is I don’t feel that it plays very well. But I needed to be very careful about the content of the message. I’m not sure if I got it right or not, but I tried as best I could to come up with a statement that I could put into a game that I could create in under 48 hours.

Early on I choose to sacrifice graphics, and go with a purely abstract game. I did not want to sensationalize with blood splatter, and after briefly considering creating animated anthropomorphic figures, but worried that whatever I might create in a short timeframe would be insufficient and might resemble offensive stereotypes. I decided to go fully abstract and use simple squares of symbolic, literal black and white to represent my people. While it was very easy to make, it afforded me time to consider how to put the message I wanted into the game. I wanted to drive home the point that you can’t tell whether a person is a criminal based on their appearance, that it is their actions that make a person a criminal. Although, really, crime is almost incidental to the reality I’m depicting — the game is really about a dystopian society where police who are sworn to protect and serve the public are allowed to get away with killing people because a corrupt system looks for any excuse to look the other way when they happen to be black.

I had a basic idea that you’d be a policeman, and you’d just patrol around on the screen while people stood about or walked around, and you’d have to figure out who among them is a criminal, and then try to arrest them or, if you wanted, you could shoot them. I gave the game three ending conditions: if you run out of bullets, if you are killed, or if you kill an innocent (white) person. And I implemented a scoring system which I felt reflects the real-world valuation we place on white and black citizens. Arresting or killing a black innocent has no consequences in the game. But arresting an innocent white person deducts points, while killing an innocent white person ends your career in an instant.

Keeping score

I struggled quite a bit with figuring out how to value the arrest and kill scores for black and white criminals. In the end, I took a base value of 100 points, because it’s a nice, round number, and then I adjusted it to reflect the bias in the legal system. I don’t know how well I did, there, but here’s how I came up with the point values: Using wikipedia, I found an article dealing with race and crime in the united states. In it, I found that the data presented in the article was fairly messy, taking numbers from different years, etc. but it said that the incarceration rate for black males is 4749 per 100,000 — about 4.8% of all black men in this country are in prison — while the incarceration rate for white males is only 487 per 100,000, or about 0.5%. I also needed to adjust for the proportion of the population that these groups represent. According to the 2010 US Census, the population classified as white represents about 63% of the total population, while blacks represent about 12%. Multiplying these percentages together, I got 0.630.05 = 0.00315, and 0.120.048 = 0.00576. Dividing these two numbers into each other, I got 0.00315/0.00576 = 0.546875, and 0.00576/0.00315 = 1.828571428571429, which I rounded to 0.5 and 1.8, respectively. I took those numbers and multiplied them by the base point value of 100, to make a black arrest worth 180 points, and a white arrest to be worth 50 points. Coming up with these numbers gave me a sick feeling.

Killing a person scores much 100x as much points as arresting them, to reflect that ending a person’s life is a higher stakes proposition than simply arresting them. Perversely, this creates incentive to shoot people, if you’re going for a high score, and for the highest score, to preferentially seek out black targets.

I never tell the player that they ought to try for a high score, but I allow the structure of the game to suggest to the player that this is what they ought to do. I expect that most people will try to play this way at first, and perhaps if they think about what the game is telling them, they might try not to shoot as much. It’s possible to play with a strategy of only arresting people, although you will score much slower, you can play longer as long as you manage to avoid being shot yourself by criminals. If you don’t care about arresting the wrong people, you can probably survive indefinitely, and in the long run the extra points you get for arresting black criminals will outweigh the penalty incurred for arresting innocent white people. In thinking about this more, it makes me question why I gave the population equal proportions of black and white people, and criminals and innocents. It might have been a more accurate simulation to give these populations the same proportions as the census and crime statistics show. But while the census figures are less likely to contain institutional bias, the crime numbers really only track incarceration, not criminality, and I don’t know where to find numbers that would reliably measure the proportion of a population that are criminals, broken down by race. So, it’s a limitation of the design, I suppose, but I’m not sure how to do better there. If I had done this, though, it would have pushed the bias toward targeting blacks much higher, because white criminals would be very rare, white innocents would be very common, and blacks would be the only safe targets for arrest and/or extra-judicial killing. This might need to go into the post-compo update, if I continue developing the game.

To provide the player with a bit of incentive to use their gun, I gave the criminals guns as well, with which they can commit murder, and some of them will try to shoot you, so there is some of the self-defense and defending the lives of others in the game, just as it is talked about in the real world whenever one of these shootings takes place. If I had to do it over again, I’d probably use the crime statistics tracked in the game to penalize your score, so that you would have a bit more direct reason to try to identify and stop the criminals. This will probably be addressed in a post-compo version as well.

The Play Experience

My process in coming up with this design was slow and meditative, so I probably spent more time thinking about the design, what it implied in terms of the message it would send, and then carefully creating a design that imparted the right message. Comparatively speaking, I spent very little time actually playing the game, and I think that shows in the play experience. I’m not really satisfied with how the game plays. The AI is extremely rudimentary, and if you allow the game to continue spawning people and don’t wipe them all up by constantly arresting or killing them, very quickly it gets to the point where there’s too much happening on the screen, and you can’t take it all in, which makes your decisions and actions less meaningful. As well, when the screen fills up, very quickly you end up accidentally colliding with people who are walking around oblivious to you, and obviously that removes the aspect of intentionality from the act of arresting them, detracting from the game’s message.

I think, if I did the design over again, I’d try to make the game slower, so that the player would be able to think about their actions and decide to do them, rather than react in a twitchy manner. Perhaps I’d reduce the number of people that can be on screen at one time (there’s currently no limit, which is bad), and I might also slow down the action so that only a smaller number of people are actively doing anything — I considered making the AI’s move in a turn-based fashion, so you could have time to monitor each individuals actions and try to figure out if they’re a criminal or not, which would give the game more of a detective-y feel to it. I’d definitely like to improve the AI a bit more so that it would make the game less random.

Overall, I’m not all that satisfied with the game as a play experience, I think it could be much better — but working on the project allowed me to work through my feelings on the current events. And, working through those thoughts was a more necessary thing for me this weekend. There’s a lot that is wrong with our country right now, especially in government and law enforcement. Reform is badly needed, and seems like a remote possibility at best. It seems like the system of checks and balances, and the rights that we are all guaranteed exist only on paper right now.

Control Schemes 0.1 released

ControlSchemes1140x360

This is a collection of scripts and macros that handle motion and action. A “control scheme” is a set of inputs and their associated actions. Add a control scheme to your player object with just two lines of code!

It is intended to handles input, motion, and action quickly and easily, while allowing you to extend to include any audio or visual effects that may be needed.

Documentation is awesome.

Currently, just two control schemes are implemented; I’ll be adding others in the future, much more is planned.

It’s currently free, as I’d like to get everyone to try it out and provide me with feedback, but when I’ve added more features I’ll be charging for it, so be sure to get it now while it’s free!

mmap mini maps is back in the GameMaker Marketplace

I’ve re-published the mmap mini maps over at the GameMaker Marketplace. The new version, 1.1.6, fixes the bug of the missing mmap constants — this time the right way, replacing the earlier workaround that I had supplied a few days ago.

Building the asset package the way I needed it was not obvious, but with the help from some GameMaker Community Forums users, I was able to learn the correct method to get the constants added to the package.

Two ways to build a Marketplace Asset

GM:S has two ways to build an Asset.

The more visible method of the two, and the one I had used at first when building my Asset, is to use the Package Manager, located in the Marketplace Menu.

Using this method, you can only build an asset which includes “project resources” — Sprites, Sounds, Backgrounds, Paths, Scripts, Shaders, Fonts, Time Lines, Objects, Rooms, or Included Files.

NOT include-able are Extensions, Macros, Game Information, or Global Game Settings. It’s a good idea to understand the rationale for not including these, and how YYG intends for GM:S users to work around these limitations:

  • It makes sense not to be able to include Extensions, because building an Asset is building an Extension, and Extensions are not designed to be nested.
  • Macros cannot be included, but I’m not clear on why. Perhaps because it’s not easy to separate built-in Macros such as GM_version and GM_build_date, and importing these would create conflicts?
  • Game Information is a deprecated legacy feature which YYG seems to be phasing out. No longer can Game Information be displayed at runtime when a game is playing. So it really only serves to exist as a readme file that you can access from within the GM:S IDE, when working on the project. The same information you might put in here is better added to an Included File.
  • Global Game Settings includes a number of fields that are developer-specific, and should not be shared, such as advertising account credentials, Facebook App ID, etc. There are some settings that would be nice if they could be included in an Asset package, such as HTML5 graphics settings, and options for Use New Audio Engine and Short-Circuit Evaluations, but if your Asset depends on such settings, the only option is to document that in your user manual so that users of the Asset can be informed of how they will need to set up their project.

The other way to create an Asset for the marketplace is to build an Extension. Right click on the Extensions folder in the Resource tree of a project, and Create Extension. Then right-click the newly created extension and Add Placeholder. The purpose of a “placeholder” is vague, but what it allows you to do is define Macros which reside at the extension level,which is done one at a time, in an interface that is different from the project-level Macros editor, and even more of a pain to use.

You can also add Functions to the Extension placeholder. You can add a code file, such as exported scripts in .gml format, or a .dll, .js, .dy-lib, etc. and then define Functions which hook up to the code file.

Once the Extension is defined, you can create an Asset out of it, by logging into Marketplace, and then right-clicking the Extension, and choosing the Create Asset Package option. Creating the Asset Package this way is much the same process as creating an Asset Package from the Marketplace menu, with the exception that the Extension that you right-clicked on will be included with the Asset Package.

Why there isn’t a simple way to include an Extension in the Package Manager build process, I don’t know. I guess the answer ultimately is that this is a new feature in GameMaker, and still in beta. The UI design is rough, inconsistent and not as obvious as it could be. Hopefully this will be addressed as the features are refined. But, for now, it is what it is, and game developers who use GM:S will just need to be aware and familiarize themselves with the differences between these two methods of building an Asset Package.