Scripting cutscenes
While watching random indie work on Twitter, I was reminded that it would be cool to support cutscenes. Now, cutscenes are not the most important part of gamedev, but it's something that I definitely envision for the game to have. They are also very presentable, and I'm currently in the mood for them, and I have lots of the underlying supporting code fresh in my head, so ... Why Not?
What are the basic ingredients of a cutscene?
- Characters talking. E.g. the player enters a level, and notices that it's remarkably cold, or that there's an eerie silence. This can really add to the atmosphere. Or, if a boss is encountered (who is intelligent and can speak), some "discussion" could happen.
- Camera work. At its most basic form, camera moves to focus on characters who are talking, or objects, or anything else.
- Characters doing things. For example, moving, attacking, shooting fireballs, etc.
- Environment effects. Rain starts, some explosion happens somewhere, etc.
Given the above, how can a cutscene be implemented? Well, I had something very important in place, which is a developer console that can execute commands. Now the trick is to be able to support all commands that could be used in a cutscene. Here are a few that I have implemented:
- cam_move [position] Moves camera to desired position
- aa [aa_name] [target] [args...] Executes an active ability (e.g. move, attack etc) for the given target entity (e.g. player, monster) with the given arguments. This was slightly tricky as a simple string needs to be converted to a fully parameterized command, but I had 70% of that done anyway.
- screenshake [duration] Executes screenshake for the given duration
- text [text] [position] Creates a text bubble at the given position (e.g. position of player character)
Now, given these, the only thing extra needed in order to implement cutscenes is to be able to schedule these: execute command, wait a bit, execute another command, wait a bit more, etc. So that's just another simple class that stores a list of commands and real-time delay between each command. Now, in order to execute the cutscene, we execute a coroutine that goes through each command, executes the command, and yields by waiting for the given amount of delay. And that's it! To add an extra bit of polish and sensibility, while the commands are executing we need to completely disable input, except a single key (e.g. Escape) that breaks the loop, thus skipping the cutscene. Below is an example video that uses just the above commands, and below that is the cutscene script.
Misc updates
I've been lazy with blog post updates due to friction in creating blog posts, which is currently done using jekyll and manually creating html files. To reduce friction, I wrote a script which, given a few parameters (date, title, representative video, etc) can create a post template, which reduces the friction. I'd love a simple offline wysiwyg editor for jekyll, but all I've seen is some cloud-based need-an-account yada yada solutions, which again increase friction, or jekyll-admin which is not good enough imo.