Game Idea: MAXIMUM UNICORN
Vulduin GameDev DK30 Fall 2021 5 3
Description
Work on creating a playable prototype/demo of my unicorn game idea, which is a little bit of Goat Simulator mixed with some Destroy All Humans. The tentative title is MAXIMUM UNICORN (yes, the title is in all caps!) named after a somewhat silly album that has nothing to do with this game other than that it features a unicorn :)
Recent Updates
Update: November 24, 2021
Well, as the few people who have been following my project might have already noticed, I kinda fell off the wagon these last couple of weeks haha. I have worked on my project a little bit here and there since my last update, but not nearly as much as I was the first two weeks of the DK30. Ultimately I’m not thrilled about how things went with this project but I’m not totally disappointed either. Since the DK30 is more about learning and making progress rather than end results I want to make one last update here to reflect on my expierience with my first DK30.
The Purpose of this Project
The goal of my project was never to have a complete game and I explictly stated that in my first update, so I’m not at all disappointed about not getting to that point. I knew the game idea I had was large in scope so that just wasn’t a realistic goal to have.
My bare minimum goal was just to get back into working on game development after putting it on the back burner for a while, and in that I was successful. I had a lot of fun working on this project over the first couple of weeks and I enjoyed brushing up on my skills and learning some new things throughout the process.
Getting my project to the point where I felt comfortable submitting it to the game jam was somewhat of a stretch goal for me, but one that I hoped and expected to achieve. Unfortunately I did not get that far, so I am a bit disappointed about that.
Things That Went Well
Early on, I was excited to get back into game dev and was spending a lot of time working on my project. I’ve dabbled with game development on and off for years now but due to lack of time, energy, and sometimes motivation, I rarely ever get a project to a point where I feel like it’s fun and worth showing to people. I almost always learn things from these projects but ultimately they end up abandoned and left to waste away somewhere on my hard drive, and I end up with nothing to show from the time I spent.
This project was meant to be the beginning of me changing that habit. I want to start getting my projects to a point where at I at least have something to show from it, and in some respects I succeeded in doing that with this one. I posted several progress updates with gifs and videos, and chatted with some of the other Day Knight game devs on the Discord channel. That’s more than I’ve ever really shared about my previous projects, so I’ll take that as a win. I also got some positive feedback on what I shared, so that was a nice bonus!
As for the project itself, I still like the game idea and think what I’ve done so far is a good start to implementing it. It needs more work than I thought it would to get to the point of being able to “feel the fun”, but I think all of the work I have done is necessary to achieve that. Two things that I’m particularly happy with are the way the game looks and the code that I wrote for the enemy AI.
As far as the looks of the game, I didn’t make any of the art myself so I can’t take credit for that, but I am pleased with how well it all blends together despite cobbling together unrelated assets from the asset store to pair with assets that I already had from other projects I’ve worked on. The toon shader I ended up using really brings it all together and gives the game a visual style that matches the light-hearted vibe that I was going for.
With the enemy AI, there’s more work to be done to get it functioning the way I ideally want it to, but I’m very happy with the code I’ve written so far. I sometimes have a tough time with code architecture/design in Unity because my OOP (Object-Oriented Programming) brain always wants to design things a certain way, but Unity lends itself to using the ECS (Entity-Component-System) way of doing things which is pretty different. I often end up spinning my wheels trying to fit a square peg into a round hole by making my MonoBehavior scripts a little too object-oriented with base classes and interfaces, but this time around I think I did a better job of embracing ECS and “compenentizing” my code which I think has made it more extensible and maintainable. The things that I need to add to it to improve the functionality shouldn’t be too hard to do from a design perspective, it’s just a matter of putting in the time and effort to do it.
Things That Went Poorly
If I could do my project over again, there are a few things that I would change. First is that I would define a more clear goal for myself and make sure that everything I do is with that goal in mind. The goal of my project was too vague and I ended up taking on a project that wasn’t conducive to achieving what I really wanted to.
To be more specific, I was upfront with the fact that I had no expectations of completing this game during the timeframe of the DK30, yet I still wanted to have something that was worth submitting to the game jam. Those thoughts don’t really line up! If submitting something to the game jam was important to me, I should’ve chose a game idea that was much smaller in scope to make that goal achievable.
As a side effect of this, I ended up losing motivation to work on my project after about 20 days because I realized that I wouldn’t be able to finish in time for the game jam. With this goal out of reach there was no more urgency to work on my project, and so I largely stopped working on it. There are some other reasons for this as well, like life just getting in the way a little bit, but it was largely due to a lack of motivation.
Lastly, I need to be more organized when it comes to working on personal projects. I have two conflicting strategies when it comes to being productive on game dev projects which I haven’t figured out the perfect balance for yet.
- Create a very well-defined plan follow that plan religiously, always doing the next thing on the list of things to do until all the things are done.
The problem with this strategy is that if you are dreading doing whatever it is you have to do next, or you’re stuck on some aspect of doing that thing, that can kill your motivation to continue working on the project.
- Follow the seratonin and just work on what you want to work on. As long as whatever you’re working on is something that needs to be worked on at some point, then you’re making progress and that’s good!
The problem with this strategy is that it’s often results in taking a very meandering path to getting to your minimum viable product, which I think is an important milestone to try to hit quickly because it let’s you get a sense of what the project could be and whether it’s worth continuing.
I think both of these strategies have their merits and the correct approach is definitely somewhere in the middle. With this project I largely followed strategy #2 and I think that set me up to fail because I needed to get to that MVP milestone in order to have something that I could submit to the game jam.
Lessons Learned
For the next DK30 / game jam there are a few things there are a few things that I plan to do differently:
-
Keep the scope of the project small!!! This is one of those things that I know in my brain, but for some reason always have a difficult time following in practice. This time, I managed to not do this by convincing myself that I don’t need to have something that’s “done” to have something that I could submit. The reality is that things always take longer than expected and that having something that is worth submitting is difficult enough to accomplish.
-
Spend a little less time working and a little more time planning. I think this will help keep me focused on the things that need to be done to get to the MVP. There’s no reason I should be spending a day getting objects floating in water to “feel right” when basic features of the game aren’t implemented yet! Once again, this is something that I know not to do but sometimes still have a hard time not doing…
-
Maybe consider working with a group on a project. I thought about this before this DK30 started, but decided not to because I was nervous about letting people down by not having enough time to commit to the project or by not being at the same skill level as the people in my group. On the flip side, I also know it could be a lot of fun and that the feeling of not wanting to let other people down is a great motivator, so I’ll definitely reconsider joining a group the next time around.
Update: November 6, 2021
I haven’t posted in a little while so I just want to give an update on my progress. Over the past week or so my productivity has definitely taken a hit, and that’s for a couple of reasons. The first is that Age of Empires IV came out so I’ve been spending a bit more time playing/watching that than I probably should be haha. The second is that I’ve been sleeping like crap for whatever reason, so I’ve had a hard time focusing when I do set aside time to work on my project. It happens, I’m not too worried about it but I’m going to make a better effort to focus and avoid distractions while I am working on my project this week. Sadly this probably means not watching Day[9] play AoE4 on my second monitor while I work :( but it is what it is, I’ll catch the VODs when I get a chance to.
Despite this week’s lull in productivity I did manage to get some work done that I can show off. I spent my time this week working on the AI units a bit more. The primary goal that I set at the end of my last update was to get AI units walking around the town looking like they are hard at work and have important places to be. The main challenge here was getting the AI pathfinding working on complex terrain. In the last update I had pathfinding working but only on flat surfaces. To get it so AI units could actually make their way around the town, they needed to be able to deal with inclines, stairs, and random bumps and objects on the ground. I’m happy to say that this is working fairly well at this point.
Here’s a quick video of one of the AI peasants strolling through a part of the map:
I also made this timelapse of the peasant walking through the entire town.
Excuse the watermark, I used a free trial Microsoft Hyperlapse to make the timelapse which I couldn’t buy even if I wanted to because the “buy” button on their website was broken lol. If anyone knows of a free/cheap video editing software to make timelapse videos in feel free to let me know on Discord.
Waypoint System
The way it works is fairly simple in the grand scheme of things but still wasn’t trivial to implement. From a high level perspective, there are “waypoint” objects placed throughout the town which are used to tell the AI where to go. In the Unity inspector, I specify a set a waypoints which I want the AI to pass through on their path and they will walk to each of those waypoints in order. There’s a toggleable flag indicating whether the path created by the waypoints is a closed loop or not, which basically just indicates what to do when the last waypoint in the list is reached. If it’s a closed loop then the AI will go back to the first waypoint, otherwise they’ll traverse the path in reverse order.
Here’s a picture of the map from a top-down perspective, with each of the waypoints shown as big green orbs:
One of the challenges of this waypoint system was making it so that I didn’t need to explicitly tell each AI how to get from one location to the next. If there are more than a few AIs in the scene (which there will be) and if their paths are long (which some will be) then the number of waypoints that I would explicitly need to populate in the inspector would easily end up being in the thousands. To get around this, I implemented Dijkstra’s algorithm which is a common algorithm used for finding the shortest path from a source node to other nodes in a graph. This makes it so I only have to specify waypoints that are “points of interest” in the AIs path, and the rest of the waypoints that need to be passed through to get from one point to the next will be figured out procedurally. The only downside is that I had to spend some time defining which waypoints are connected (i.e. edges in the graph), but I only have to do that one time and then it is usable by all AIs so it’s definitely less tedious than the alternative.
Low-Level Pathfinding
At a lower level, each AI is using AStar on a grid graph to do more granular pathfinding (i.e. walking around obstacles rather than through them). The grid graph is created by raycasting downwards from the sky. If the raycast at a particular point in the graph hits a pathable surface then the point is considered pathable, otherwise it is not pathable. This can get tricky with archways and overpass bridges, but it’s doable with some clever usage of layer masks to specify what objects should be considered/ignored by the raycasts.
Here’s an image of what the grid graph looks like (blue is pathable, red is not pathable):
On top of this there is a local avoidance algorithm that helps AI units avoid bumping into each other or getting stuck on dynamic objects in the scene (i.e. objects with colliders that could block their pathing but aren’t included in the AStar grid graph since they can move around). Both the AStar pathfinding and local avoidance are done by a great asset pack that I have used a few times now, it’s a bit pricey but it works great and has saved me a ton of time on several projects.
Potential Improvements
Right now, the AIs only work because of very specific tuning of things like how fast they move, their mass, drag, etc. I also had to make a hack for stairs where they get an extra boost when walking up an incline. Inclines are detected by doing a couple of raycasts, one at their feet and one around knee height. If the bottom raycast hits and the top one does not then the AI assumes it is on an incline and gets an extra boost in the direction they’re moving. It’s a sloppy hack, but it gets them around well enough to be fine for now.
The reason I’m having issues with these types of things is that the velocities of AI units are influenced by two things; 1) the physics system and 2) their own pathfinding algorithm. Problems arise when the forces applied by physics outweigh the forces applied by pathfinding. For example, in the case of stairs the problem is that the downward velocity of gravity is overpowering the upward velocity of the pathfinding algorithm that is trying to move up the stairs. This is why my hack of adding some extra force when an incline is detected works.
After a bit of research, I think I have an idea about how to fix this problem but probably won’t do so for the DK30 because the time and effort it would take probably isn’t worth it at this point. I think the solution is to split the character into two separate objects, one which is affected by physics and one which is not. The object that is not affected by physics will do the pathfinding, while the physics object will have the character model and will always be moving towards the pathfinding object. This will be done by applying force in the appropriate direction and the magnitude of that force will increase as the two objects get farther apart. In general the two objects should be very close together, but in the case of stairs they’ll get farther apart as the character struggles to move up the incline, and that should result in the pathfinding object “dragging” the character up the stairs. This is a simplified explanation as there are edge cases that make things more complicated, like what to do when the physics object gets knocked far away from the pathfinding object somehow (by the horn attack of the player, for example), but that’s the basic idea. If I continue with this project after the DK30 I’ll have to delve into this problem some more.
Update: October 28, 2021
Big update today! I wanted to post an update or two before now but things came up and I just never got around to it, so I have a lot to share in today’s update.
Toon shader
Let’s start with the visuals – I decided to go with a toony look for the game. It just seems natural considering the tone of the game is meant to be light-hearted and silly. An added bonus is that I think it makes it less noticeable that I am mixing assets from different asset packs that all have their own art styles. I’ve been trying to pick assets that aren’t TOO different from each other, but options are limited and the toon shader helps make them look more cohesive. Here are a couple of screenshots with and without this shader (and some light post-processing).
Enemy AI Units
As you can see in the screenshot I added an enemy unit, the Scout, which will be one of the earliest units you encounter that can actually attack you (there will also be Peasants, but they likely won’t be able to attack). I spent a good amount of time working on the AI for Scouts/Archers (since they’ll behave the same) and I’m pretty happy with it so far. I went with a typical state machine design, and right now the states they have are Idle, Wander, Chase, and Attack.
- Idle - Self explanatory, the Scout just stands there and looks pretty
- Wander - Pick a random spot within a radius and walk to it
- Chase - If the player is within the aggro range and is in line of sight, run towards the player
- Attack - If the player is within attack range and is in line of sight, attack the player
Health and Damage System
In my last update I mentioned that I would likely tackle the player and enemy health/damage system, which I did. There’s no UI for it yet, but the code is there for the player and enemies to beat each other up and will play their death animation when their health is depleted.
I need to add some effects to make the hits feel better and be more visually readable, that might be in the next update.
Next Steps
At this point, I have a lot of the building blocks needed to start making this an actual game rather than a lost/unsupervised baby unicorn simulator lol. To do this, I’ll need to do a few things:
Populate the World with AI Units
I have a basic enemy AI working but that is more for military units, I need to get some Peasants wandering around just doing random stuff. These are the people that you’ll be running around and harassing early in the game. Military units will probably only appear once you start cause enough mayhem to draw some attention to yourself.
Interactable Objects
There are a lot of random objects in the world but they aren’t interactable in the sense that they have no physics simulation at the moment. I’ll need to make it so they can be interacted with so you can do stuff like knock over carts,water buckets, bags of grain, etc, break barrels, splash around in the water fountain, all sorts of fun stuff that will piss off those overly serious Peasants!
Player Abilities
Right now the player can’t do anything but run around, jump, and attack with their horn. I need to add some more for the player to do to make things a little more fun. Eventually there will be more attacks the player can use, and I have some ideas for that, but I don’t want the game to start out by just running around the town murdering people. The start of the game is meant to be more about goofing around and causing mayhem, and eventually things will escalate to violence.
In order achieve this I’m thinking about stealing a page out of Goat Simulator’s book and adding a mechanic where you can grab things with your tongue and drag them around with you, swing them around, throw them, etc. This is a fun and really silly phyics-based mechanic that I think fits the tone I’m aiming for. It opens up some gameplay possibilities too, like being able to pick up swords/shields with your tongue and use them in combat by swinging them around like a lunatic.
Stretch Goals
As I alluded to in my last update, there are a couple of features that I have in mind that I am considering stretch goals which I would ideally like to implement but are likely outside of the scope of a DK30 considering the timeframe. These features are active ragdoll characters and procedurally destructible buildings/objects.
Disclaimer
I’m not an artist, and even as a programmer I don’t want to spend my time reinventing the wheel so I’m making heavy use of asset packs for this project. My goal is to make a playable game, and leveraging asset packs helps clear the way for me to do this rather than getting bogged down making crappy art or writing code to do things like pathfinding that others have already spent considerable time implementing much better than I likely would be able to without spending considerable time on it myself. I just wanted to mention this to be transparent about the fact that not everything you see is my own work, and making all of this stuff would likely take months even if I had all the skills to do it, which I don’t!
Update: October 20, 2021
Spent the first couple of days of this DK30 working on getting the basic player character controls and animations working, as well as the third-person camera controls. I had a little more trouble than anticipated (haven’t worked in 3D in a while) but all said and done I’m pretty happy with what I have so far. I made this little unicorn play-pen to test out the controls.
The camera is rotated around the player character by moving the mouse around, and it has some nice features like zooming in when the character would be obstructed by an object, and not clipping through walls or the character (when zoomed in).
The player controls are pretty simple, W and S move forwards and backwards, while A and D rotate the character left and right, space is used to jump, and left mouse is used to attack. The attack applies a force to objects that it hits, so that should be fun once I get some more objects in there to knock around :)
I think the next thing that I will work on is some of the boring but important stuff like the health/damage system. This should be fairly straightforward so it shouldn’t take too long.
Something that I would like to implement for this game, but seems a little daunting due to the time constraints, is active ragdoll physics. For anyone unfamiliar with the term, what it basically means is that characters are both animated and affected by physics at the same time. An example game that makes heavy use of this is Gang Beasts.
My game is meant to be a very silly game (the theme is funny physics after all!) and I feel like this is a feature that would really amp up the silliness, I’m just trying to decide if the time and effort is worth the result.
Update: October 18, 2021
For my first update I want to outline the game I intend to make! I’ve mulled over a few different ideas since deciding to participate in this DK30 / game jam, but I ultimately settled on this one because it’s the project that got me the most excited.
Unfortunately it’s also probably the largest in scope… I originally wanted to make a small 2D game, but this is a decent sized 3D game. Whoops! I think that’s fine as long as I am realistic with my expectations going into it. I will NOT have a complete game by the end of the DK30, and that’s okay!
All I’m hoping to do is create something that can be played around with and at least somewhat resembles the game I envision. If I get that far, I’ll consider it a success!
Inspirations
- Goat Simulator
- Destroy All Humans
Backstory
Once upon a time there was a town nearby a magical forest whose people hunted and drank the blood of unicorns, believing that their magic contained medicinal properties that were key to good fortune and vitality. When one of the townspeople’s hunts results in the deaths of several of the forest’s elder unicorns, one small unicorn who witnessed the atrocities becomes blinded by rage and sets out to destroy the town and its people in a quest for vengeance!
Game Idea
The player controls a unicorn whose mission is to wreak as much havoc on the townspeople as possible! Total destruction is the ultimate goal, but inflicting enough damage to dissuade the townspeople from continuing their practice of hunting unicorns is also an acceptable result.
Due to the unicorn’s small stature, the initial attacks don’t amount to much more than minor harassment; knocking down villagers, breaking fences, tipping over food carts, etc. However, the more damage the unicorn inflicts the bigger and more powerful it grows. At maximum strength, the unicorn is massive enough to crush buildings under it’s hooves and develops powerful magical abilities like being able to shoot laser beams from its eyes!
Objective
The objective of the game is get points by wreaking havoc on the town and it’s people. The amount of points awarded will be proportional to the damage caused (i.e. bumping into a person might give you 10 points, but destroying a building gives you 1000). There may be special tasks that are challenging and award extra points if completed.
Mechanics and Features
The following is a breakdown of the mechanics and features that I see being in the game if my vision for it were to be fully realized:
Gameplay Mechanics
- Health and Damage System
- Player Controls and Abilities
- Unlockable Abilities
- Points System
- Progressive Difficulty
- Enemy Unit AI
Ancillary Features
- Main Menu
- Options Menu
- Persistent High Scores / Leaderboards
Non-Essential Features
- Unicorn Customization
- Procedural Destruction
This of course is far too much to do for a 30-day project so I don’t expect to get all or even most of these things done, but I think it’s a good mental exercise to think this through. I think it helps with deciding what to prioritize and coming up with a realistic expectation for where the project will be at the end of the 30 days.
The things that I am hoping to have at least somewhat implemented by the end of the 30 days are:
- Health and Damage System
- Player Controls and Abilities
- Unlockable Abilities
- Points System
- Enemy Unit AI
- Main Menu
- Options Menu
Most of these will likely be implemented in a limited capacity. For example the system for unlocking abilities may be very simplistic, such as unlocking specific abilities when reaching a specific score. A more complicated version of this system would be a skill tree system that gives the player more choice. Enemy unit AI is another example where the implementation will likely be VERY basic (a more complex AI could be a DK30 project in itself). If enemies have pathfinding and chase/attack the unicorn when within a certain range, I think that is an acceptable place to be at the end of the 30 days.
Ultimately, I have no expectations for this project to resemble a complete game 30 days from now. All I expect is to have something that gets the idea of the game across and is fun to play around in. My hope is that the project is in a place that I feel like it’s worth continuing beyond the end of the DK30.
Estimated Timeframe
Oct 19th - Nov 18th
Week 1 Goal
- Settle on the overarching design of the game
- Create a plan for what needs to be included in a minimum viable product (MVP)
- Create new Unity project and begin coding core features/mechanics
- Determine what art assets I am going to use (from the Unity asset store), and what assets (if any) I will need to make
Week 2 Goal
- Continue coding core features/mechanics. Should have at least some of the core mechanics/features in a working state by the end of this week
Week 3 Goal
- Finish working on core mechanics/features. Game should be playable by the end of this week, even if mechanics/features are minimally implemented and non-essential features are missing
- Start working on supporting features like menu system, user-interface, etc.
Week 4 Goal
- Polish essential mechanics/features
- Add in music and sound effects
- Play-test as much as possible to identify and fix bugs