mgoadric

LD 42

Baggage Claim Post-Mortem

My LD42 entry Baggage Claim is complete!

baggage-cover-image.png

It's a stressful microgame where you must clear luggage as fast as you can. Each new bag must be shifted on the carousel within 5 seconds of it arriving or you run out of space and the game is over. You score for every piece you get off the carousel.

Jam Submission Page: https://ldjam.com/events/ludum-dare/42/baggage-claim

Post-Mortem

I teach computer science at a small liberal-arts college in Arkansas. One of my goals for my sabbatical (yay sabbatical!) this year is to participate in Ludum Dare jams. I want to further test my design and programming skills, and learn better ways to incorporate it into my Game Development class, which I teach every two years. LD42 was my third Ludum Dare, and the first time participating without my students, where I have previously assigned Ludum Dare as part of a final project. I miss the community aspect of developing and playtesting along with my students as they sprint to finish their first real game, but I'm looking forward to having time to play and rate more games online. Here's my post-mortem analysis of what went well this time and what needs improving for the next jam.

Jam Goals

  • Integrate theme
  • Simple to play
  • Audience of at least 3 yr old
  • Refresh Unity skills

I really like how a simple theme can help constrain the game design process. Instead of just trying out anything as you make the game, it gives inspiration to new mechanics and helps eliminate choices that won’t match the theme. I was also looking to make something simple, enough that my 3 year old son could be able to play, but still interesting for me to play. And since the last time I touched Unity was May 2017, I wasn't looking to push and learn anything new, but hoping this would be a good way to get my skills back up to speed as I enter my year of Unity game development.

Recipe for Success

It's really hard to make a game in a weekend! For Baggage Claim, I spent roughly 15 hours over the weekend in evenings and my son’s nap-times. Overall, I’m happy with where my game ended up from the initial design. I’m starting to get a feel for the workflow needed to be successful, similar to the work cycle I advise for my students who participate in the Mathematical Contest in Modeling each year. I think one more time through the jam and I'll be able to write up a general primer for my students to guide their weekend schedules; here is what worked this time.

Brainstorm

I took the first two hours of the jam to write down various ideas inspired by the theme and also fitting my other jam goals. It helped to constantly write every minute, keeping the ideas flowing and spinning until something clicked. Bouncing from cars in a traffic jam to trains delivering cargo to a boat, anything that would fill up physical space and need to be cleared out, I finally settled on my son's excitement with the airport baggage carousels on our recent cross-country trip. My game would be about getting luggage off the carousel before it clogged up, and to make it more interesting, there would be concentric carousels traveling in opposite directions, where you had to match up shapes to move from one to the other.

Find good libraries

One I settled on the luggage idea, I set out to find some reference on coding up smooth object movement on a curve, so I could use it for the rounded edged of the carousel belts. I quickly stumbled upon the Hermite Spline Controller page that was an amazing reference and starting point for my code!

750px-SplinePicture.png

From the above image, it looked exactly like what I would need with some tweaks, you set down reference points, and your object could loop through them smoothly, and all the math is hidden. I had just spent the last two months coding on a separate research project in C#, and my skills with Visual Studio were fresh, time to get the latest updates to Unity and start coding!

Step-by-step development

One of the hardest things to do in software development is to find the pathway from the empty project to a working product. You know what you want to happen at the end, and might be tempted to code and code and code lots of scripts and create lots of gameObjects, leaving testing until everything is created. I see my intro programming students make this mistake time and time again. But the more you code, the more likely it is that you will make a mistake early and need to rework all of your later coding.

I have found the most successful way forward is to split up your project into very small pieces, each of which can be measured and tested for success. The way to eat the big apple is with lots of small savory bites. You might not end up exactly where you thought the goal was, but you will continually be making progress and having something in a working state. Install a version control system like Github and be sure to make a commit every hour or so. You can see my code and progress for this project over at my RunningOutOfSpace repository.

As a side note, this type of iterative testing and development model would drive my father crazy whenever we worked on a woodworking project together. He would always measure twice and cut once, but I wanted to see the project and assembly tested and fit together at each step, always verifying that it would actually work and we were on the right direction, and it saved us from making large mistakes more than once.

One thing moving

First up was learning how the library worked. The big lesson is that when you see a tutorial you like, actually try to do the tutorial! I could have made a few pieces of luggage on the screen and copied bits of code into a script, but that would have most likely resulted in a few hours frustration since I didn't know how it worked yet. Instead, I spent time getting the tutorial to work, and then I could then extend and modify it to meet my needs, always making changes from a working system.

Multiple things moving

Next, time to get more things moving on the screen. All of them on one belt would follow the same route, and I was lucky the library script was abstracted in the right way so I could make multiple moving objects from the same path waypoints. I found a nice free image, and whala, moving luggage!

2018-08-11 10.05.03.gif

Reverse belt

A little bit more coding, and I could reverse the direction of the objects by loading the waypoints backward as I added in my objects and created their path. With a simple bool added to the script, a conveyor belt became reversible by checking a box in the inspector.

Separate luggage from belt pieces

I had luggage flying around now, but to make it move from one belt to another, I needed to separate out the luggage from the conveyor belt. Time to make some more gameObjects, and give the Luggage and BeltPieces different scripts. I ended up with the BeltPiece having a Luggage component, and it would detect collisions with other BeltPieces to transfer luggage. The Luggage script would be in charge of doing a lerp to move from one BeltPiece to the next. I also set up a LuggageMaker in the center, and gave everything RigidBody2Ds and Collider2Ds to detect when pieces were close.

ezgif.com-gif-maker.gif

Automated movement

The pieces were coming together, now time to focus on game flow. To know if my idea of movement between the carousels was going to work, I created some methods to fire every time a valid collision occured. By putting off the user interaction, I could see the best-case scenario of playing the game to watch for buildup scenarios. In this stage I adjusted some of the collision sizes, moved a few waypoints to give better opportunity for collisions, added some connection LineRenderers and highlighted matches with opacity settings.

ezgif.com-gif-maker(1).gif

User directed movement

Finally, time to move from just a simulation to a game! A few OnMouseDown() methods later, and the user can click active connections to make the luggage move! Getting the state right was a little puzzle, and it's still not fully working, but I activated each BeltPiece when it entered the collision with another BeltPiece, and deactivated it when it left. If it activated with two, it would remember the most recent one.

UI and Sound

At last, time to polish and deploy! A quick trip to bfxr and I was ready with some sound clips to give the user some feedback on their actions, and tick the time away. I overlaid some UI elements for a start button and a TextMeshPro spot for tracking the score, and it was a working game! Hooray!

Also, to have the game be replayable, a little trick was necessary. In Unity, you can make a Singleton instance to track the game state and status of the other object. This makes it easy to have the UI tools get game data without needing component links to prefabs and generated content.

Here is the final gameplay!

2018-08-13 11.17.40.gif

Abstraction can come later

When I look at my code, there are many places where I think there should be abstraction, but due to the time crunch, I left these until later. For instance, I made a separate prefab for each of the five luggage types instead of a general prefab that I configured later. I also hand-placed all the movement points for each carousel. If I wanted to extend this game with new levels or change the number of carousels, I would definitely need to refactor what I did, but the time investment would not have paid off for the jam.

Prototype is good enough: Stay away from shiny time sinks

At the end of the jam, I feel what you need most is to have something working, not the best game ever. The jam is to put you through the pressure cooker and give you a deadline to make something work. When I've used Ludum Dare in my classes, the jam is only the first step of my student's final project. We take at least a week to playtest the games in class and on campus, and a large portion of their grade is determined by how much they are able to improve on their weekend sprint.

You can see that come through in my Baggage Claim entry. I made quick use of online public domain clip art and stayed away from the temptation to spend tons of time making new icons for the passengers at the end. And you can still see the Unity blue screen in the background. Again, what works for me is to keep the focus on making incremental and testable progress toward what will get you a working game.

Future Plans

I made a game! It worked! But there's always room to think about what could go better next time.

Build early to find build bugs

This was my biggest mistake of the jam. On Monday morning, I started getting the design complete and tried my first WebGL build from Unity. The progress bar made it to 90%, then froze and my processor and fan started spinning away. Oh no! I spent an hour worrying and reading about IL2CPP, thinking that was where the build was getting stuck, and trying to reconfigure my build preferences. Finally, I tried one more time, went for a snack break, and came back to the build finishing, hooray! Had I been building earlier I would have been prepared for the delay time and not freaked out with only hours left in the jam.

Allow time for tuning

The mechanics worked as I expected, but I never really had time to tune the game play experience. Most of the numbers hardcoded into the game are just what I thought looked good at the beginning of development, with some small tweaks at the end. While I think an earlier focus on the player interaction would have slowed down development time, getting the mechanics working is only half of the task, and I'll put aside more time for playtesting a working game at the end next time.

Explaining the rules

Like my previous entries, I have a hard time explaining the rules in the game itself, I rely too much on the entry page and editing the html build site for detailing what is going on. Again, if I could get to a working prototype earlier, then I would be able to spend more time on the UI and a tutorial level with popups for the rules. This will probably affect my scores, but as I said, to get the game completed, compromised abound.

Build new skills

I relied on what was familiar to me with making this game, a 2D simple interactive setup with collisions and mouse input. While that's necessary to getting a complete game at the end, I will be spending time between now and the next jam building up new skills. I want to practice making an RPG, an isometric design, use my Oculus setup for VR design, etc, so that I can hit the next jam with new possibilities for development.

Twitch

My work environment for making this game was just my laptop in various rooms around the house. Because the jam is on the weekend, that's just what is going to happen for me, but I hope in the months to come, I will be streaming to Twitch with my office setup as I make more games this year.

Conclusion

Thanks for reading! I am continually impressed by the Ludum Dare community, and find the emphasis on post-mortem posts to be an amazing source of personal reflection and community building. I hope you found something of value in my analysis. Off to start playtesting and rating the other LD42 games! Congratulations to everyone!

VR Games?

Anyone making VR games for Ludum Dare? Is there an easy way to tag and search games by genre, platform, etc?

I found one by chance, a VR game written in Unity, and was happily able to get it up and running on my Oculus Rift. I would love to test out some more and provide feedback, leave me a comment link with your game and I'll try it out. Thanks!

LD 43

Lessons Learned Integrating Ludum Dare into an Intro Game Development Course

I'm an assistant professor of computer science at Hendrix College, a small liberal arts college in Conway, Arkansas. In Spring 2015, I taught my first course in game development. I decided to use Ludum Dare as the focus of our final project. This amazing community takes seriously the efforts of amateur developers as they are making progress toward personal goals, and offered exactly the feedback and encouragement I wanted to provide for my students. My first attempt didn't go exactly as planned, but I used what I learned to make the second time around much better, and I hope that my experience is useful for others interested in attempting a similar course structure.

First Attempt

Throughout my 2015 course, I taught my students with a standard curriculum, giving lectures and assigning labs related to using the Unity physics engine, animations, and 3D models, and programming steering behaviors and AI. However, when the final project arrived, they felt utterly unprepared. We had focused on developing skills in an academic setting, but the students lacked the necessary mental and logistical frameworks to get a game up and working in a short amount of time. Each team submitted a barely-working prototype and was somewhat discouraged by their efforts.

Ludum Dare 32 Entries

ld32.png

Second Attempt

Our first experience led me to make a large overhaul with drastic improvements for the Spring 2017 version of CSCI 370 : Interactive Game Development by adding in multiple mini-james, a more integrated asset tool section, and Twitch streaming feedback assignments.

Mini-Jams

The biggest revision I made was to introduce bi-weekly lab assignments explicitly focused on making small games, for a total of 5 games developed before the final Ludum Dare project. From the moment they were introduced to Unity, we talked about building viable working prototypes. This need for their submissions to be playable and fun was emphasized by setting aside time following each lab deadline for me to play their games and provide live feedback with often hilarious bugs being discovered. Students rotated through different teams for each game, so they could build connections across the class and share new skills. The theme for each game was decided randomly using an online noun generator, providing freedom to innovate within somewhat arbitrary constraints. As new coding skills were added, the requirements and expectations for the next game expanded. Where the first game only needed to incorporate physics, collisions, and mouse input, by the end it was routine for my students to incorporate custom GUI elements and NPC AI characters, and they had multiple solid experiences starting a game from scratch.

Integrated Tools

Second, in the initial course iteration, students gave small presentations on helpful asset tools, such as sprite creators, terrain editors, and music generators, in the two weeks before Ludum Dare. This turned out to be too late to be useful, and most tools were ignored in their final project work. In the Spring 2017 iteration, I scheduled these demos to be staggered earlier in the course, so that as our Unity skills grew, so too did their outside tools. This turned out to provide the right level of integration, and I found them refining their assets and improving their game quality at a much faster rate.

Twitch Streaming

Third, I increased the amount of Twitch streaming in the course. To introduce my students to the wider gaming community and give us all a common corpus of games as reference throughout the semester, the first assignment in the course requires the students to play at least 10 selected games from diverse genres and broadcast themselves on Twitch for at least one. In their broadcast, they needed to be reflecting on the elements of the game and how it was creating emotions, choices, and strategies for the player. Because they had already learned about streaming, I integrated a peer feedback element into each of their game assignment, where they would record a stream of themselves play each other’s games and commenting in the same way as their first assignment. I also modelled this behavior myself in class, streaming each of my lectures to Twitch to maintain them as class notes for further study, especially the days when I playtested their game assignments.

Ludum Dare 38 Entries

Because of these changes, my students felt poised to successfully create a game for Ludum Dare, and saw it as more intense, compressed version of our bi-weekly labs instead of a brand new experience. Their resulting games made great use of asset tools and GUI interactions and overall were were much more complete upon entry. Two teams even submitted their games to Ludum Dare Twitch streamers, and were very pleased with the feedback they received and the interactions possible with the wider community.

Screen Shot 2018-11-27 at 9.54.12 AM.png

As for the final project itself, participation in Ludum Dare is only half the project, and students could still recover from an unsuccessful entry. I emphasized to them the importance of reflection on successes and failures in their weekend, which fits very well with the Ludum Dare tradition of making post-mortem blogs after submitting your game. Students then spent at least a week trying to fixing all the bugs and expanded their content to fully realize their game vision. I coordinated an opportunity for outside playtesting by hosting an arcade with our submissions in the student union building on campus, and welcomed others to play and provide feedback for their game. To wrap up their work, students made a video trailer for their game and demonstrated to the class their progress since submitting their game for Ludum Dare.

Conclusions

Overall, my students have greatly benefited from this Ludum Dare course integration. By being responsible to an outside audience through creating Ludum Dare entries and streaming on Twitch, my students showed increased engagement with the material and improved quality of work. I found that for this to be successful, the course structure must scaffold and complement the skills needed to excel in game jams.

Of course, coupling a course with an external competition can present difficulties. And it did! First, the timing of Ludum Dare is out of my control, so I needed to rearrange my syllabus once the dates were announced. Luckily our semester schedule overlapped well with the April dates for both course iterations, leaving at least a week following the competition for playtesting and revision. Second, in 2017, Ludum Dare 38 moved to a new hosting website. There were multiple server load issues and broken pieces, as the website was updated often while the competition was in motion. Game submission was delayed for a least a day, and the voting/feedback mechanisms were even further delayed. It was critical to be flexible in my expectations for the students when these outside issues occurred.

Finally, I have found it enormously helpful to participate in Ludum Dare myself alongside my students in the course. I gained first-hand knowledge of any issues they should encounter, with submissions or posting feedback, so I could better guide them through the process on submission day. Also, as I rated other games after the competition, I saw the benefits of the “karma” system, which helps others find your game faster when you have provided quality feedback elsewhere in the competition, and encouraged my students daily to rate and comment on other games. I have since separately participated in Ludum Dare 42, and hope to help another instructor deploy a similar course structure this spring!

Good luck to everyone this weekend in Ludum Dare 43!

What We Hold In Our Hearts

diaryArtboard 1.png

It is finished! Would love to hear your thoughts, I'll start playing and rating games tomorrow. Good luck to everyone finishing up!

https://ldjam.com/events/ludum-dare/43/what-we-hold-in-our-hearts

Looking to test Oculus VR games

I was able to find a few VR games last jam, and it was a joy to get them running on my Oculus Rift. I know it is hard to find playtesters for these games, so if you made one for this jam and are looking for feedback, let me know and I will give them a try!

Looking to play Oculus VR entries

I was able to find a few VR games last jam, and it was a joy to get them running on my Oculus Rift. I know it is hard to find playtesters for these games, so if you made one for this jam and are looking for feedback, or saw someone else's VR entry, let me know and I will give them a try!

What We Hold In Our Hearts : 20+ Ratings!

diaryArtboard 1.png

https://ldjam.com/events/ludum-dare/43/what-we-hold-in-our-hearts

Just passed the magic 20 ratings threshold, hooray! If you're looking for a quick running platformer game, I'd love to hear your feedback!

I'll be playing more games this afternoon, leave me a comment below if you have a WebGL game and I'll try to play it! Thanks again!

Post Mortem: What We Hold In Our Hearts

Thank you everyone for the feedback and ratings on my game, What We Hold In Our Hearts! Here's how my numbers tallied up this time:

LD43 Ratings

And using the nifty software over at ldstats.info, here's how I've fared over my past four Ludum Dare entries.

LD Historical Graph

I was happy to see my mood rating increase from previous contests, since that is where I spent most of my brainpower this time. Overall, I wish my ratings would have been higher. But, I learned a lot from the process and feedback by trying something new and different to me, which was my whole goal for submitting. Time for my development story and lessons learned.

Brainstorming

When the theme was announced, I brainstormed like everyone, trying to decide my particular angle on "sacrifice." My go-to game style is a puzzle game, I'm very familiar with how to code them up, but I'm pushing myself out of this box this year. Whereas in previous contests, the theme was wrapped up in mechanical twists, this time I wanted to make a game dripping with theme and mood and worry less about innovation and mechanics.

I finally settled on making a game where the player was trying to save themselves and their possessions following some unnamed disaster. I wanted to make the player feel like they were making a sacrifice themselves, in the vein of the Companion Cube from Portal, and not just playing a game about sacrifice. It felt too easy to set up a situation where the easy and expected thing to do to win the game was for the character to sacrifice something (people, money, items, etc.) with no consequence to the player.

Luckily, I found a list of items people most regret leaving behind in emergencies, and built my game around these ideas. I sketched out the following images to be my valuable possessions:

  • War Medals
  • Personal Diaries
  • Children's Stuffed Animal
  • Passport
  • Jewelry
  • Family Photographs

itemsholdAsset 13@3x.png

My thought was that somehow in the game, you would form a connection to these items, and then be forced to leave something behind, causing player devastation and inconsolable tears. Well, that was the plan, anyway.

Parallax

My game would involve running, lots of running. That in itself can be boring with just pressing a button to run, so I tried to add player interest in a few ways. First, the running would need to be rhythmic and need constant attention. I initially thought of having the player hit keys for the left and right foot of the character. I eventually simplified this to be repeated hitting of the "<" and ">" keys on the keyboard to go left and right.

Second, the scenery needed to be evocative of the theme. I'd taught my students about parallax backgrounds, using ideas from this excellent tutorial, but had never wrapped a game around the concept. This was the time!

tutorial

I started out by copying an old demo project, which as we'll see later, was not the best idea. It got me started with some initial code for the parallax, which I was able to swap out with some cold forest/swamp background images I made.

parallaxbackground.png

I was heavily inspired by the Forbidden Forest images in the first Harry Potter movie, as you can see here.

original.gif

Anima2D

Now, to make some characters that run. I'd just learned about the Anima2D package in Unity in October, as I developed a puzzle game called Bunny Kiss.

Wanting to see if I could transfer what I learned, I set about making a simple flat character in Illustrator and give it a skeleton for movement in Anima2D.

walkcycle.jpg

To make it move, I decided to implement a walk cycle based on an image from Lynda.com.

anima2dcharacter.png

And we have a running character! Hooray! Time to implement the actual game mechanics, or so I thought.

ezgif.com-resize(1).gif

Crash and Recovery

On Sunday afternoon, my bad decision earlier caught up with me. Because I'd copied a Unity 5 project to start, and was now using Unity 2018, weird things kept happening. In particular, the Invalid AABB errors (which no one really seems to know why they occur) were overwhelming my development process. My computer was losing battery power, and even when plugged in, there were huge lags in trying to get the game to run. And every so often, Unity would just close on me. Also, my hard drive was mysteriously filling up, I suspected with all of these errors being logged in cache somewhere. So, I followed the recommendations to wipe the Unity cache for the project.

TERRIBLE IDEA!

I got back some of my hard drive space, but somehow lost all of my prefabs, and animations, and skeletons, and AUGH! Nothing worked!

It was time to start over with a fresh Unity project. Sigh.

I still had all my graphic assets and code for the game, so by the evening, I was able to get back up to where I was before, with much cleaner setup, and no more mysterious AABB errors. My character animation was more like limping than running, but whatever, it needed to be finished.

Also, I haven't learned how to substitute out the images in Anima2D once the skeleton has been constructed, so for the other characters in the game, I changed their brightness to make them distinguishable. I was running out of time, and needed to focus on making an actual game instead of just a running character.

Timing and Tuning

I settled on having three characters in the game, you, your friend, and the unnamed enemies who are after you. Your friend runs up and says you have to go, then starts running, and the enemies are not too far behind. You needed to run after your friend, not too fast or you would start to drop your precious items, but not too slow, or you would get caught by the enemies. I found using very small exponential growth in the speeds of the characters was the right way to go, starting out the friend and enemies slower than you can go, but by the time the minute is up, the friend is about your speed but the enemies are much faster, as the following graph shows.

hearts-speeds.png

As for timing, I was able place the enemies just far enough behind the friend that it would take them about 45 seconds to reach the friend. Also, if you did nothing when the game started, the enemies would catch you in about 4 seconds.

hearts-distance.png

In my dialog manager script, the friend will signal that the next safehouse was found at 50 seconds, and the safehouse is entered about 5 seconds later. So if you just go slow and track your friends speed, you will both get caught too early! However, you get to slowly bump up your speed as you run, if you try to run again before the animation has finished. And in doing so, you can push a little on your friend in front of you and make their speed faster.

But if you bump up your speed too much, then you get clumsy and start dropping items. You stay clumsy until you pick up items you dropped. And your speed is reset each time you stop moving back to your default speed, so you need to be going faster at the end of the game or you are caught. I wanted to make it a very narrow balance for the player to walk, and with some good tweaking of the numbers, I think it works well. Ultimately, I wanted to make it even tighter, in that you would have to make at least one sacrifice of an item to make it to the end, but I let that go just to get the game working.

One other thing I thought was essential, was that I would never outright tell the player the right rhythm for tapping or the speeds of the characters, they would need to figure it all out through playing and losing the game. I did add one indicator, a repeated clip of labored breathing to let you know you were starting to go too fast and become clumsy. I did test it after the deadline of adding in a clumsy meter for you to know your exact level, but it made the game too easy to play, it was much better to have it all work by intuition.

Finally, I added in the GUI elements and dialog, set up the selection of the initial items, and it was time to submit!

diaryArtboard 1.png

Feedback

This was my first time making a platformer game with dialog and narrative, and I learned a lot. Most players felt the game was too short, and would be a great setup for a longer game with more variety in the missions to get from safehouse to safehouse. I agree. While I could usually churn out enough levels of a puzzle game to make a good demo prototype, this proved very hard to do in the limited jam window, especially with my reboot on Sunday, and the messy get-it-done code that resulted. I've since cleaned up the structure to allow for future extensions, making a class that specifically manages the dialog state and timing, hopefully I'll have time to revisit this game soon. I now feel like I have enough experience to guide better platformer projects by my students and a nice working tutorial game to demonstrate the concepts in class next time I teach my game design course.

streamers.png

Watching ElysiaGriffin and YourBr0ther and a few others play my game on their Twitch streams was amazing! Their play followed the narrative arc I was hoping players would experience, (get trampled, go too fast, learn to pick things up, then try to work out the right speed) and I got to see first-hand how someone would navigate the system with my minimal explanations. You should definitely try to get your game playtested in this way, Twitch streamers for Ludum Dare games are awesome!

Here's a link to the post jam version, and check out the Github repo to see more details of how it was made.

Thanks for reading and all the feedback, see you next LDJAM!

Ludum Dare 45

Untitled Ghost Game is complete!

Screenshot 1.png

We made it! Come play our game!

  • https://ldjam.com/events/ludum-dare/45/untitled-ghost-game