Development Progress Update, Week 4

Busy != Productivity…*

This has been a busy, though not an especially fruitful week in terms of development progress. I got side tracked trying to learn a couple of new techniques I’d need (shaders and surfaces) and I’m continuing to troubleshoot code signing certificate issues…

For the prior, I just stumbled on the fix this afternoon while trying to make a pause function – more on that on a separate post when I have the time/motivation to write it.

On the later, much of what I have encountered keeps coming back to the certificate signing request (.CSR) and private key export (.PFX/.PVK). I’ve been using OpenSSL, which my provider doesn’t seem to support, instead preferring that I use Window’s certificate snap-in.

This would be fine if I were on a domain, but I’m not…Ergo, there’s no certificate enrollment policy as there is no domain controller or active directory service. I had a spare PC sitting around (my wife’s old gaming desktop which had since been replaced by a much nicer gaming laptop), so I decided to plug it in and see if it still ran.

When I did this, I was greeted with a long series of short beeps (power failure) followed by repeated attempts to start itself only to immediately shutdown again. After digging around in the garage, I found a craptastic 500W PSU to replace the relatively nice 700W OCZ Stealth Steam modular PSU that was in it…

This allowed it to boot, and a cursory look around the machine seemed to indicate that it was good working condition otherwise.

Next Steps

Once I get the “server” up and running, setup all the required services and so forth, I should be able to sort out the SSL issue… I feel as though I’m spending way too much time on this, but without it, I’m not only out $140 on something I can’t use, but I’m also unable to distribute “trustworthy” applications.

 

*The prefix “!” means NOT (i.e. ‘!=’ is NOT Equal to)

Development Progress Update, Week 3

Summary

Game prototype is 67% complete!

I finally received verification on my code-signing certificate. While I was able to successfully sign an .exe file using the cert, I’m still getting a SmartScreen warning when running the file.

Further research suggests that I might need an Extended Verification (EV) code signing certificate (which isn’t available from my Certificate Authority (CA)), and/or publish the application on the Windows App Store.

I’ve received assurances from my CA that the certificate I purchased from them should work fine, and that the problem was with my Certificate Signing Request (CSR). Having rekeyed the request at least twice already, I feel sure that I’ve done everything correctly.

The only anomaly at this point is that Publisher is being displayed as the entire Subject string (i.e. state, city, country, organization etc.) rather than just the common name, “V-Toad Games.”

This is a big enough issue to warrant my full attention as a SmartScreen warning could deter potential players from running my games.

Development Progress Update, Week 2

Summary

Game prototype is 65% complete!

I lost a couple of work days due to illness…

I managed to get combination actions working (i.e. Jump+Down to drop down from a one-way platform). I may extend this later to allow look-down (using just the down key) to shift the camera a bit further once I learn how to use the view functions.

With the help of YYG Support, I was able to get the HTML5 module working, more on that later, and look for an update to my previous post.

I coded a virtual D-Pad for use on touch-screen devices, and while it works perfectly, I would need to adjust the resolution for it work on mobile devices.

On the business side, I’ve gotten together the required documentation needed to setup my Code Signing Certificate request submitted, and am awaiting verification.

What I’ve Completed This Week

Coding

  • Wrapped up player movement (combination keys to jump down)
  • Got HTML5 Module working
  • Got Virtual D-Pad (touch screen support) for mobile devices working
  • Got the trap mechanic started, but needs more thought with regard to implementation

Assets

  • N/A

Miscellaneous

  • Setup an account on GameJolt (allows me to publish and sell games both in .EXE and HTML5, hosted on their site)
  • Received an update on my Code Signing Certificate and provided additional documentation
  • Upgraded GMS to v1.9.525

 

What I’m Working on Next Week

Coding

  • Complete trap placement mechanic
    • Spawn cursor corners, spaced to fit any size trap object
    • Spawn/placement sound effects
    • Placement coding with checks to verify place is empty (no stacking/placement inside walls etc.)
  • Begin work on enemy AI

Assets

  • Background textures artwork
  • Scenery/flavor object artwork
  • Continue work on BGM 2, 3 and 4
  • Other SFX as needed

Miscellaneous

  • Follow up on Code Signing Certificate
  • Digitally sign an .EXE file and test it

Development Progress Update, Week 1

Summary

Game prototype is 60% complete!

I’ve begun coding the basic features of game, starting player control. This is the most important piece as the majority of the time spent in-game will be centered on movement and exploration.

I’ve coded it to utilize both Keyboard and Gamepad support (should I elect to port this to Xbox Live, PlayStation 3 & 4). The next piece will be getting the trap mechanic working, followed by Enemy AI (which are my goals for next week).

What I’ve Completed This Week

Coding

  • Basic platform physics (gravity, collision, one-way platforms)
  • Player movement: left-right, variable jump height, drop-down*
    • Keyboard support (WASD, [space])
    • Gamepad support (analog stick and d-pad) – Tested on a Logitech F310
  • Sound Engine:
    • Walking sound effects play and change based on surfaces
    • Landing sound effects play and change based on surfaces hit
    • Sound effects use random variable pitch to break up monotony
  • Basic inventory array
    • Keeps track of what spells you have
    • Allows you to toggle betwen spells

Assets

  • Sound effects and music:
    • Jumping
    • Landing on normal surfaces
    • Landing on wet surfaces
    • Walking on normal surfaces
    • Walking on wet surfaces
    • Collecting currency
    • Collecting resources
    • Collecting spells/secrets
    • Collecting bonus items
    • Detriments
    • Lob
    • Two kinds of projectiles
    • Damage
    • Title screen BGM (Background Music)
    • First level BGM
  • Player sprite animations:
    • movement (left,right)
    • Idle
    • Jumping
    • Falling
  • Resource sprite animations:
    • Arcanum (currency)
    • Iron Nodule (resource)

Miscellaneous

  • Converted all .WAV and .MP3 files to .OGG (faster and smaller)
  • Registered the DBA (fictitious name) of my business with the state
  • Send an inquiry to the SSL provider to request a Code-Signing Certificate (required the business to be registered)
  • Updated the vtoadgames.com website to use SSL
  • Acquired GMS Professional (v1.4)  and the HMTL5 Module**

*I’d like to modify this to use a combination of the Jump button and down, but haven’t gotten that working yet

**It doesn’t work out of the box, and I have no idea what I have to do differently to ensure that my games will work when ported to HTML5. Submitted a support request 5 days ago, awaiting feedback.

What I’m Working on Next Week

Coding

  • Wrap up player movement (combination keys to jump down)
  • Complete trap placement mechanic
    • Movement of the trap ahead of the player
    • Spawn cursor corners, spaced to fit any size trap object
    • Spawn/placement sound effects
    • Placement coding with checks to verify place is empty (no stacking/placement inside walls etc.)
  • Begin work on enemy AI

Assets

  • Background textures artwork
  • Scenery/flavor object artwork
  • Continue work on BGM 2, 3 and 4
  • Other SFX as needed

Miscellaneous

  • Follow up on Code Signing Certificate
  • Follow up on HTML5 export module issues

State of the Toad, February 2017

UPDATE 2/09/2017: After about a week of back and forth with YYG support, I was able to get the HTML5 module working. It turns out that GMS v1.4 had several bugs preventing most HTML5 games from running properly when using certain functions.

Eventually, I was instructed to download the “Early Access” build (v1.9.525) which resolved this issue. There were a few more code optimizations I needed to make, but the game-breaking bugs were gone.

The Good

With a helping hand from an old and dear friend of mine, I was finally able to make the some important steps forward. Some of you may notice that www.vtoadgames.com now supports SSL!

I’m also in the process of obtaining a Code Signing Certificate so that Windows Exports (.exe files) won’t display a Smartscreen warning that the publisher (yours truly) is unknown – I should have that today if everything is in order.

Additionally, I’ve also purchased GMS Professional and the HTML5 export module as I feel pretty comfortable with GML  at this point.

The Bad

YoYo Games, creators of GameMaker Studio (GMS),  have elected to go the way GameSalad and discontinue offering a free ‘standard’ edition of their product once GameMaker Studio 2 (currently in beta) is launched.

While those who already obtained a free Standard Edition license for 1.4x will get to keep it, no one else will be able to get one going forward. A similar thing happened with GameSalad, which went to a subscription model after discontinuing it’s free version.

Cui Bono?

Surely not YoYo Games…The reason GameMaker Studio was so appealing to many Students and Hobbyists was it’s accessibility – they said it themselves:

We want to make game creation accessible to everyone. We think that once people jump in and start creating a game, they’ll see firsthand how easy it is with GameMaker: Studio. – James Foreman, April 11, 2016. GameMaker Studio: Standard Goes Free FAQ

While most users would be content with the Standard version, some might decide they have a knack for it and take the plunge. The only thing that cutting out the free version does is bar entry for those who aren’t prepared to spend $150 to satisfy their curiosity. I know, I was one of them. Had I not had the opportunity to learn GML before buying the Professional Edition, I probably would not have.

With that said, if you still on the fence, pick up 1.4 Standard for free while you still can!

The Ugly

Please see the update above.

I purchased the HTML5 Export Module with the reasonable expectation that a program which performed flawlessly as a Windows target and compiled .EXE file would work fine when ported to HTML5. I was wrong…

Just about everything failed from the particle effects, collision events and everything in between, making the game unplayable.  I submitted a ticket to YYG, but I’ll probably have to go back through the code and optimize it to get it to work. In any case, it was a good learning experience…

###

Welp, back to finishing up the last Level of the GPC!

More Missing Pieces… :(

Level 15 begins with an introduction:

“You have learned how to store numbers and text using variables, lists, maps, and grids.  In this level you will learn one final way to store values – Arrays.”
– Level 15 Intro, www.gameprogrammingcourse.com

Variables? Check.

Lists? Check.

Maps? Nope. This would have covered key, value pairs (i.e. Health Potions: 5) . There are about 19 functions that are associated with type of data structure, so it would have been nice to know.

Grids? This isn’t what we talked about in Level 12, but rather 2-dimensional arrays (like a table) for holding strings or real numbers. There are over 3 dozen functions associated with these, and like Maps, they were never mentioned in the previous Levels.

Meanwhile, back at the YouTube Channel…

The playlist for Level 15 was entitled, “Arrays and Matrices,” and while Arrays are covered, Matrices are not. There are 3 videos broken up into parts A, B and C, but C isn’t referenced on the website.

The corresponding project files consist of an empty project (L15_01_.gmx), a starter project for Part A, skipped B and went straight to an all-in-one project, L15_01_ABC.gmx…at least all of the challenge-related files were there this time!

 

###

So what gives? Well, between hundreds of YouTube videos, a website, GameMaker projects, resource files and his lesson plans, I could see where things might get out of sync…

Nevertheless, as my GPC course comes to a close, I feel that a complete review will be in order. SPOILER ALERT: It’s still the best set of GML lessons out there!

 

Another Missing Piece…

The title of this post is used in ambivalent mode; it both introduced a missing component that made a simple inventory system possible (Level 13, lessons 2-4) and was missing a project file (14-01-X3-Start.gmk), preventing me getting a crack at the last challenge of Level 14…

I checked the resources folder (there was no sub-folder for Level 14), double checked the projects folder, no dice… 🙁

Off to bed now, and tomorrow, I’ll tackle Arrays!

 

Losing Steam, Second Wind

I just finished Level 12 out of 17 of the GPC. The momentum I built up going into Level 5 has been slowing to a crawl as I stumbled over structural incongruitiesweak examples, bugs, and project file configuration issues.

The Groove (or Rhythm or Flow…)

I am most productive when I find my ‘groove’. This happens when I’ve overcome my learning curve, have developed a pattern of work,  then get into a rhythm where I can knock out task after task by reusing the same steps.

Jimmy Diresta explains that first time you try something is the most difficult; you ‘go to school’ on the first one, and get progressively better and better – by time you finish, you’re an expert.

Matthew Inman made an incredible post on this subject, describing the agony and joy of creation…a few non sequiturs aside, he eventually gets to the meat of issue – how great and wonderful things can result from sweating over tasks that are often tedious and frustrating in and of themselves.

My problem is that I’m a perfectionist. If I encounter something that isn’t working to my satisfaction, I can’t ignore it – I have to ‘fix’ it. Maybe this is a characteristic of a good programmer, but it’s utterly frustrating when I’m working on it, and enormously satisfying when I get something to work properly…

The trouble, it seems, is that the content is getting thinner and thinner,  and the issues referenced above that are breaking my ‘flow’ are getting more and more numerous. At a guess, I’d say that these last few videos were produced at a busier time than the others, and as a result, he simply didn’t have the time required to carefully plan and produce them as well as he’d like.

Whatever the reason, I have to remind myself that no matter how annoyed I get with this course, it’s still free of charge, and of far superior quality to any other GML ‘tutorials’ on YouTube. More importantly, distractions, bugs and problem solving (especially when the problem is more complex than it first appeared) are all part of programming – so I’d best get used to them 🙂 .

That said, on with the lessons…

###

Levels 9-11 (Doesn’t that look ominous?)

Level 9 was more or less a rehash of Level 7, focusing on instance IDs, along with another ‘cheat sheet’ from the resource folder. The two share a lot of parallels, and might be better off merged into one big lesson rather than two disjointed ones. There was even a loop snuck into one of the project files to create more enemies, but that wasn’t covered as part of the lesson.

Level 10 was one of the shortest lessons so far, and anyone who attempted to include a sound as suggested in Challenge 10-01 part C will discover that they’ll need to enable the New Audio Engine (Global Game Settings > General > Use New Audio Engine) before they’ll hear anything.

Level 11 was a letdown. I was really looking forward to Lists, but the only output method covered was the number of total items in the list (e.g. the ds_list_size function). The examples in the lessons didn’t really fit my concept of ‘inventory’ – that is, being able to output all the values in the list, or how many of each unique value there were (e.g. 2 Burgers, 2 Apples etc.). I suspect that this will be covered later in Level 13 (Loops).

###

This brings us up to…

Level 12: Grid Game Concepts

Grid games can cover everything from board games (checkers, chess etc.) to turn-based and real-time strategy games to classic video games like Namco’s Pac-Man.

In all cases, movement in a grid game is fixed rather than free form. GPC 12-01-A covers movement, and attempts to tackle the issue of getting hung on on corners due to the collision geometry.

The Lesson’s Solution:

Make the sprites equally sized (32×32 pixels in this case) and use a collision mask of 32×32 to ensure that they stay within the confines of the maze corridors. That’s a good start.

Next, he introduces how to manually code keyboard and collision events inside a Step event like so:

if keyboard_check(vk_right)=true and place_meeting(x+4,y,o_block)=false {
 x=x+4
 }
 
if keyboard_check(vk_left)=true and place_meeting(x-4,y,o_block)=false {
 x=x-4 
 }

if keyboard_check(vk_up)=true and place_meeting(x,y-4,o_block)=false {
 y=y-4 
 }

if keyboard_check(vk_down)=true and place_meeting(x,y+4,o_block)=false {
 y=y+4 
 }

What the code is actually doing is checking to see if the player object will collide with a wall object (o_block), and if not (false), advance the player 4 pixels in the direction given.

Why this is an unsatisfactory approach:

Since are moving the player 4 pixels at a time, you have to manually tap back and forth until you are perfectly aligned or you will still get hung up on corners. This isn’t much of a problem when moving around 90 degree turns, becomes an issue when trying to get through ‘four-way’ and ‘T’ intersections.

How to fix it using only what we’ve covered so far up though Level 12:

When I set out to tackle this, the logic went something like so…

  1. Find a location 32 pixels (one character or tile length) ahead of whatever direction I was going
  2. Move to that location
  3. Stop moving when you reach it

I tried using the move_towards_point function using a variable (e.g. target=o_player.x+32) in conjunction with distance_to_point but found that it target would always be 32 pixels further ahead, so it would never close the gap and would move in that direction infinitely. The solution would have to be something relative to, but external from the player object.

That’s when it hit me; why not use another object? So here’s what I did (coded in the o_player object)…

Press D-Key Event:

//create a new object as a waypoint for the player to move towards
//move towards the target's coordinates at a speed of '4'
target=instance_create(x+60, y, o_target)
move_towards_point (target.x,target.y,4)

Collision with o_target Event:

//Destroy the o_target object on collision
with other {
instance_destroy()
}

//Stop the player
speed=0

Some of you may be looking at that code and scratching your heads – why 60 pixels? Well after lots of trial and error, I worked out that in order to move 32 pixels from where you were, you’d have to include the width/height of the player object (+32 pixels), giving you a total of 64.

When I tried 64, I found that I was stopping just short of where I needed to be, and worked out that the collision wasn’t actually detected when the edges of the two object met, but when the player object had overlapped it by the designated speed (4 pixels). So, 64-4=60, which places you at exactly 32 pixels over every time you press the key.

Once I had that working, it was time to clean up the code and put some utility conditions in it to prevent a keystroke from changing direction before you got to your destination, an additional event to stop you when you hit a wall, and to destroy any target objects you can’t reach (i.e. behind a wall) and some additional variables to be able to control the distance (pdist) and speed (pspd).

In the Press D-Key Event:

// check to see if character is moving
if moving=0 {
//set moving to true & destroy the old target
 moving=1
 with o_target {
 instance_destroy()
 }
//move target right by 'pdist' pixels at a speed of 'pspd'
 target=instance_create(x+pdist,y,o_target)
 move_towards_point(target.x,target.y,pspd)
}

Add moving=0 to the end of the o_target and o_block collision events and that’s pretty much it! Now using the Key Press event rather than just the Keyboard event will cause you to take a single step 32 pixels in whatever direction you are heading assuming you adjust the +/- pdist variable depending on whether you are going left (x-pdist), right (x+pdist), up (y-pdist) or down (y+pdist).

So once I got everything working, I swapped the WASD Events over from Key Press back to Keyboard and viola, true grid movement!

 

Image Credit: Don Quixote, oil on canvas painting by Jean-Baptiste-Camille Corot, 1868.

A Challenge Within a Challenge!

I’m up to Level 08, Lesson 03, and was working my way through the challenge that followed.

In playing through the game as-is, there a couple of notable bugs above and beyond what the challenge required:

  1. The collision event for the potion was missing altogether – easy fix
    givePlayerHealth(25)
    with other {
         instance_destroy()
    }

     

  2. The “health bar” didn’t accurately reflect the current hitpoints! Take a good look at the screen capture from his preview video below:

 

Look closely and you can clearly see “HP: 5” yet the health bar is nearly 1/3rd full! That doesn’t look right… so what’s wrong with it?

This one was a bit more tricky because neither draw_rectangle nor var have been covered yet…granted, the challenge was to change the color of the rectangle based on the # of hp, not to create a hitpoint bar from scratch – even so, it bothered me that it was broken and I wanted to see if I could troubleshoot and fix it…here’s the original code:

var healthBarWidth=100
var maxHealth=100
draw_set_color (c_white)
draw_rectangle(150,50,200+hp/maxHealth*healthBarWidth, 60, false)
draw_set_color(c_black)
draw_rectangle(150,50,200+healthBarWidth, 60, true)

The syntax for the draw_rectangle function is as follows:

draw_rectangle(x1, y1, x2, y2, true or false) where

x1=the x location of the upper left-hand corner of your rectangle
y1=the y location of the upper left-hand corner of your rectangle
x2=the x location of the lower right-hand corner of your rectangle
y2=the y location of the lower right-hand corner of your rectangle
true=filled with whatever your draw_set_color is
false=empty (transparent) with a 1 pixel border

Confused? Well here’s an illustration I made to visualize it better:

Now lets apply that to the code above. Working through his arithmetic for the filled (false) rectangle, here’s what you get for the x2 values if you substitute the variables for their numbers:

200+0/100*100=200 (0 hp)
200+100/100*100=300
(100 hp)

Expressed in code, it would look like this:

draw_rectangle(150,50,200,60,false)//0 hp
draw_rectangle(150,50,300,60,false)//100 hp

…and output like this (assuming you include the border rectangle):


The left edge (x1) starts at 150 pixels in, and the right edge ends at 300 pixels, giving you an overall length of 150 pixels (300-150=150) along the x axis.

When the player has 0 hp, the left edge is not 150, but 200, leaving you with a 50 pixel (1/3rd) wide rectangle, which is exactly what you see in the screenshot above.

So I dug into the code and came up with the simplest solution. This was the result:

Notice that it says “HP: 50” and the bar is exactly half way!

So how did I fix it?

Simple – move the left edge over by 50 pixels, giving the overall length of both rectangles to be 100 pixels rather than 150, removing the 50 pixel lead:

//health bar draw code - the first rectangle draws the filled color
//the second rectangle draws the border
draw_set_color (getBarColor())
draw_rectangle(200,50,200+hp,60,false)
draw_set_color(c_black)
draw_rectangle(200,50,300,60,true)

It’s no accident that my code is absent the healthBarWidth and maxHealth variables – since my healthbar is 100 pixels in length, the simplest solution was to shorten the bar. The reason those are included is size the fill rectangle proportionately to the amount of hp you have remaining so that you can name the hp bar longer or shorter depending on your needs.

But you can’t use the code from the original project file as-is…

First, you’d need to set minimum left-edge of x2 to match x1 for your filled rectangle. So instead of:

 draw_rectangle(150,50,200+hp/maxHealth*healthBarWidth, 60, false)

You’d replace 200+hp… with 150+hp…:

draw_rectangle(150,50,150+hp/maxHealth*healthBarWidth, 60, false)

Secondly, you’d need to change maxHealth proportionate to the total amount of your hp (100) with respect to the overall length of your rectangle (150). This would give you 100/150 or 2/3rds (66.6% repeating).

Since hp is evenly divisible by the length of the health bar, this presents a problem as putting in var maxHealth=66 is pretty close, but not a pixel perfect fit inside the border rectangle (it’s about 4 or 5 pixels off).

Nevertheless, if I just had to make a health bar bigger or smaller than 100 pixels, I’d try to use something that divides evenly, hide it using depth and alpha channels, or leave off the border altogether. There may be more elegant ways to solve it, but it’s nearly 2am here and I think I’ve learned what I wanted to from this exercise 😐 .

Into the Deep End…

I’ve just finished Levels 06 and 07 of the GPC. Not much to say about the first lessons within Level 06 – they introduced GMS’ built-in image editor – while adequate for what it is, there many better tools available.

Moving on, the one good take-away from Level 06 was learning that image animations don’t start from the first frame by default – instead, they pick up wherever you are within each step.

So if you trigger an action that calls for an animation change (e.g. transitioning from idle to movement), the second animation (movement) will NOT begin on frame 0 by default, instead, it will pick up whether the animation should have been with respect to the current step!

As such, it’s useful to lead with image_index=0 to ensure that the animations start where they are supposed to.

###

Level 07 was short, and lacked the continuity established in the previous lessons. Functions were thrown about in rapid succession without stopping to really explain what they did, instead, an exercise in, “RTM,” though not in so many words 🙂 .

Aside, January 11, 2017: I concede that there are hundreds, if not thousands of built-in GML functions, and not all of them could be covered in even a ~120 hour course. Moreover, some may be too obscure to be useful for most students, and the intent was to get the user familiar with the help file and looking up function syntax when needed.

Fair enough – so why kick up a fuss about it now? Well, to this point (with the exception of Level 04), the course followed a very effective formula:

Introduce a new concept, usually built upon a solid foundation of core skills developed throughout the course. In order for the concept to be useful, it has to be framed in a context that’s meaningful to the student. Absent that, the exercise becomes meaningless and rote; disconnected from other concepts and quickly forgotten.

My recommendation would be to change the name of Level 07 to “Vector Functions and Collision Checking” – I would remove “scripts” because that isn’t really covered until Level 08, and only hinted at in Level 07.

While Level 07 defines what Functions/Methods and Arguments/Parameters are, we’ve been using them since Level 02, and could continue using them blissfully ignorant of what they are called, that is until Level 08 where it really becomes necessary to understand them.

Take that out, and what you are left with are numerous examples, all concerning either Vector or Collision Checking functions (i.e. point_direction, position_empty, point_in_circle, instance_furthest/nearest…), and use examples of games where these are useful or necessary (e.g. tower defense, homing missiles etc.).

Level 08 is more promising thus far, but looking ahead, the good stuff is going to be found in Levels 11-15.