One month ago, I released a software product called "SimplePath" on the Unity Asset Store. SimplePath is a pathfinding middleware for the Unity game engine, which I recently started using after leaving my full-time job as an AI Programmer at Nihilistic Software, a company focused on the console gaming market. I had never released a piece of software on my own, and I noticed the Unity community's desire for a pathfinding software, so I felt like this was a good opportunity to see what it's like to self-release a small scale product.
In the rest of this article I'm going to discuss the most interesting things that I learned while developing SimplePath, whether they are related to technology, business, marketing, or advertising. First I'll give a background of SimplePath, then I'll write about some key learnings, and finally I'll go into the technical details.
If you are unfamiliar with the product, here's the official video.
For more details, here are some links to give you some context:
Here are a few interesting statistics since the product was released:
- 3rd highest grossing package on the Unity Asset Store.
- Most popular and highest grossing in the "Scripting Packages" category.
- Priced at $60, selling around 3 copies per day on average.
- $4200 gross in 1 month (70% for me, 30% for Unity).
Features & Challenges
Screenshot 1: SimplePath uses the funnel algorithm for path-smoothing, which works on both grids and navigation meshes.
Screenshot 2: Agents dynamically avoid obstacles. Each obstacle has a "footprint," which represents the terrain blocked by the obstacle.
Screenshot 3: Many agents can quickly pathfind at once, at the cost of extra memory. Each planner has its own memory pool.
Screenshot 4: The chase behavior is inherently supported through a MoveToObject request. This request can handle the dynamic nature of a moving target because paths are re-planned at regular intervals.
Screenshot 5: A simple grid-based terrain editing interface was necessary to allow users to get agents navigating quickly from the get-go.
Screenshot 6: 6. Uneven terrain was challenging to implement because different games often have different ways of handling collision response with uneven terrain, in order to achieve the desired experience. In the end, I exposed several acceleration parameters to the user, such as gravitational acceleration.
Early Product Decisions
When I first decided to make SimplePath, the core idea was to make a pathfinding middleware that would be really good at pathfinding, and would be easy to use. Over the course of the product's development (2 weeks), I maintained this core idea, but expanded it a bit more. So let me first describe what I saw as the defining features of SimplePath. These are the features that I thought would make SimplePath successful, before it was released.
First, SimplePath offers everything you need to get your agents moving in game. At the time of release, none of the other existing Unity pathfinding solutions offered this. They either offered pathfinding, steering, or terrain editing tools, but none of them offered all of these features together. The Unity community (500K users) is very focused around accessibility, because Unity as a product focuses on accessibility. Many users of Unity are not programmers, and they want solutions that will work without having to write any code.
“Unity users want solutions that will work without having to write any code.”
Second, SimplePath supports dynamic obstacles at the planning level, which no other product supports. I see dynamic obstacle avoidance as a tool that makes the developer's life easier, and increases the production quality of the game. Several times I've worked on games that didn't support dynamic obstacle avoidance at the planning level. While this feature wasn't exactly necessary for the games at hand, it would have been helpful. As a result, we ended up bending the game's design to not require dynamic obstacle avoidance at the planning level.
Third, I "hired" a friend to do the graphics work, because I thought marketing the product was important, and I wanted better marketing than my competitors. The graphics consists of 4 variously sized images that are shown in the Unity Asset Store, along with a few screenshots. He did all of the graphics, and I did the screenshots. Fortunately, my friend was kind enough to help me out for free (thanks Dave Reed Monroe). My only expense for the whole project was the price of taking him and his wife out to brunch.
Fourth, I wanted the software to be extensible enough to allow the user to plug-in their own terrain, and steering solutions. I thought this was important because terrain representation and steering solutions differ based upon the type of game you are making, and I wanted to provide pathfinding tools for as large of a market as possible.
And finally, I felt confident that I could hit a higher bar of quality than the other packages, because I've had nearly four years of experience working on navigation for commercial games.
Now that SimplePath has been released for nearly a month, I feel that I have successfully accomplished my goals. SimplePath is one of the highest grossing packages on Unity, several customers have created their own steering solutions, there haven't been any bugs reported since release (though there have been feature requests), and the product continues to maintain a steady sales rate (roughly 3 copies per day, at $60 per copy). If I could add one feature to the product, it would be built-in support for navigation meshes. You can extend SimplePath to use a navigation mesh (via inheritance), but as I said before, Unity users don't want to code. Adding support for navigation meshes isn't an easy task. It requires adding the tools to create navigation meshes, and that's far too much work. There's no way I'm going to be able to make something better than Recast, and even if I did, the small increase in sales wouldn't be worth the colossal amount of work required.
Next I'll discuss a few key things that I learned. These key-learnings are common sense when it comes to shipping a product, but I still think the anecdotal evidence is interesting.
Don't take too much time. From start to finish, SimplePath took 2 weeks to implement and release. Keep in mind I still had a full-time job, so I was coding SimplePath for two weeks after I got home from my regular job. Though, I had most of the programming completed before this two week period, for other programming projects I would work on at home. Regardless, I decided from the start that I wouldn't spend more than two weeks on this project, because there's not a huge market (500K Unity users), and not a huge amount of money to be made.
For Unity users, accessibility is number one. I really underestimated the number of Unity users that are not programmers. After spending some time trolling the forums, I realized that many of the users wanted a product that didn't require them to write code.
Supporting the product is more time consuming than creating it. In the two weeks I spent creating SimplePath, I think I spent about 8 days coding, and 6 days testing and marketing (ex: creating demo videos, conversing with the UI artist, creating screenshots and videos, writing product descriptions, and documentation).
The primary means for supporting the product is through the forums. In one month there has been more than 250 forum posts about SimplePath, and around 125 of those posts came from me. Additionally, I released one version update (version 1.1) after gathering feedback through the forums. This update included better support for navigating across uneven terrain, performance improvements, and several other minor features.
Now let's get into the more technical details of SimplePath. There's nothing that's terribly complex about the implementation. But I see it as a technical success because it is very polished. The core idea behind the software is to provide a robust pathfinding solution that allows you to get up and running quickly, and to make it easy to plug-in your own solutions for steering, or your own terrain representation, or whatever else you want to provide that is custom. For example, to define your own steering you just need to inherit from the SteeringAgentComponent. Or to define your own terrain representation, you inherit from IPathTerrain.
But there are a few coding tricks in SimplePath that could be interesting to the AI community. For example, there is a replan rate that allows you to control how often each path is replanned. I think the more common solution is to invalidate paths by sending messages to the navigation system as soon as an object blocks the path. Instead of doing that I just assume the world is dynamic, and I replan the paths at a regular interval (tunable), which makes the code interface a bit cleaner and less complicated.
Also, it is interesting to note that the points for all path solutions will always be in a valid location in the terrain space. If the agent tries to pick a destination covered by an obstacle, or outside of the grid, then that destination point will be clamped into a valid position in the terrain space. There's a less obvious problem with navigation, which is this: what do you do when your AI get themselves into locations outside the terrain representation, because physics or some other external force pushed them there? To solve this problem I just do a very simple local search, with a shallow depth, to find the first valid position near the agent. I think it is important to have a well-defined solution for your AI's behavior even outside of the terrain representation, otherwise you get undefined results (e.g. the funnel algorithm will not work properly if one of the points is outside of the terrain space).
The net result of the replan rate, and always using valid terrain points, is quite interesting. The agents continually re-assert the validity of their navigation, every time the replan timer expires. For example, let's say that an agent is navigating from A to B, and a giant rock drops down in front of him. If the replan timer is set to 0.5 seconds (which is the default value in SimplePath), then there is a maximum of 0.5 seconds for the agent to potentially have an invalid path and do something dumb, like run into the rock. 0.5 seconds is so short that most gamers won't notice. Once the timer expires, the path is replanned, and the agent will smoothly navigate around the rock. To see this behavior in action, go to the SimplePath 1.0 demo video, and scrub forward to the 18 second marker.
I've had a great experience working on SimplePath. It was a really great way to learn more about what it takes to ship a successful product, on a very small scale. If you are planning on creating your own Scripting Package for the Unity Asset Store, my advice is to pick something you know how to do well, make sure the product can be used by someone who doesn't know how to program, time-box your schedule to something shorter than a month, and find someone who knows how to make graphics for you!