Yep, I made an entire game in Reaper! A side scroller with enemies, difficulties and procedually generated levels. Without a single line of code! I insisted of only using macros and custom actions.
In this post I want to give you an in depth explanation of what's going on under the hood, which custom actions I made, which scripts I used an how its all setup inside of Reaper. I actually have no idea how to script, so there's no scriptininvolved during making of this game. Only a combination of various actions and scripts that other have made which can all be found in ReaPack or at the Stash.
Gameplay You control a midi item with the arrows. Up and down on the tracks and left and right by grid points. Keep going right to avoid the 'evil playback cursor' aka the Creaper. Let's imagine theplayback cursor is ahuge Spider-like monster hunting you down!
Collecting purple blocks increases the BPM but theoretically gives you more points or maybe hurts the Creaper more.
Collecting brown midi items slows the BPM down hence making it easier but giving you less points.
Avoid the black midi items, if you collide into those you are game over!
You win the game by making it all the way to the right, doing so a picture pops up showing "Win" and stopping the playback. Getting caught by the playback cursor or colliding into a Avoider-item stops the playback and shows a message with "Game Over"
Underneath there's a cheesy midi soundtrack going on, that adapts according to how you play the game. (Playing it faster or slower). As a challenge for myself I decided to only use ReaSynth.
First of all, I use a lot of midi commands to run actions. Normally it only works with controller surface, but the awesome plugin MidiReaControlPathlet's Repaer redirect midi to itself, which makes it possible to activate actions by midi items. No, seriously, I don't know what I should have done without this plugin! It saved the whole game
The controls are pretty straight forward. Up is "Item edit: Move item/envelope points up one track/a bit" and Right is "Item edit: Move items/envelope points right by grid size" + 2 Custom Actions that I call "Move block to playback cursor and play" and "Find Player" which I will get back to later.
GameZoom sets the horizontal zoom to an empty midi item on track 1 and sets the vertical zoom to "Level tracks" which is then later defined in the custom Action "Selected Level tracks". They are split up, so that is easily possible to expand or reduce the track view in the game. The track GameZoom pumps a steady pulse on every beat, activating the action GameZoom via MidiReaControlPath. The action moves the timeline-midi item one beat as well. In all my actions, but especially this one I was very careful not using any scripts or actions moving the playback cursor, which turned out to be difficult!
Select level tracks
This one basically select the children tracks of Track 1 folder and unselects the upper and the buttom one. Conveniently I found an action called Xenakios/SWS: Unselect tracks with 'BUSS' in name which is a bit hacky, but works well. Optimally it would work with any track name
Move block to playback cursor and play is the juicy but simple action where all the interactive gameplay happens. All the objects are pr default muted, but when they are collided with by the Player-item, they get unmuted and set to the playback cursor and thereby immediately activated. One flawback though, is that I could only get it to work with the action "Item: Select next adjacent non-overlapping item"
I tried with solutions where it would select overlapping items then deselecting the player, but that gave problems when colliding with the objects from the middle or from behind. Any ideas here are highly appreciated!
Each block-category has a specific midi value, which activates a specific action. T.ex. the item DoubleBPM activates the item called DoubleBPM by playing the midi note 0.
Generating static level
Basically I have created a duplicate of the level tracks, containing the same amount of tracks, where I put all my objects that are static for each level. That includes the tutorial blocks and the Win-block you collect at the end. All the items on those tracks get copied unto the level tracks and then deleted afterwards. Easy peasy!
The same goes for my "Spider"-objects, though I have made them dance by shuffling around their own positions. Pretty fun! It can be seen in the gameplay video here
Procedural level generating
This section has been the most complex to figure out and have resolved in the most grey hair. The system is not perfect, it could be automatised more. I would love to hear some suggestions or feedback for improvement
The folder track GameLogic contains the children Find and Objects.
In short there's a midi item on each Find-track called Player, DoubleBPM, Avoider etc. The action FindPlayer selects the first item on FindPlayer-track, selects all items with similar name and then deselects the one at FindPlayer-track, so it never moves. It's only purpose is to locate other similar items.
FindPlayer runs the console command S*FindPlayer* which I have bunch of in a text-file so they automatically appear in the action menu. Pretty neat. Wish you could do the same for items.
At the Level Tracks I placed a bunch of markers at more or less random position. I then position all my objects at certain markers, shuffle the tracks and then shuffle the items. The custom action for one of the Avoiders looks something like this
Then I they are all placed in action called "Position all objects" which positions all the procedural objects, then the static objects and finally the Player at the right position. The order is important to not screw up all the items (which I found out the hard way)
Want to try it out?
Here's dropbox link to a portable install for Mac. In there you can also find the project files and the relevant custom commands, if the portable install doesn't work for you. Perhaps someone smarter than me can show me how I can streamline this process and share it with Windows users as well?
You might want to redirect the location for the images which are in /Game images
As well as the MidiReaControlPath which is in /VST And make sure that all thy keycommands are active. You can change the keyboard commands as you wish, but leave the midi mappings.
If you manage to play the game and it suddenly doesn't work, don't worry. Just load the Fixed Level again (without saving first) and everything should be fine. Otherwise I take no responsibility in the game working! Maybe it does, maybe it doesn't.
The game is not bug free, by far! And it still needs some development to improve the game. For instance, here's are some things I would love to add to the game
- Boss fight
- Objects make a sound when they are activated (maybe using ReaSampler)
- Using time signature as scoreboard. How fun would it be to have a score on 75/4?
I also plan to make a git for the project, making it easier to update and access.
If you want to help out, here's some actions/scripts I would love to use, but I don't know how
- Select/Unselect a specific item (t.ex. Player)
- Pick a random marker
- Display huge time signature
- Select overlapping items
- Select next adjacent overlapping item
- Input text from textfile (for instance for using Find)
+ more stuff I can't think of in the moment!
If you have any questions or ideas, please write them I'm all ears and would love to know what you think of all this madness!
You are also welcome to follow my youtube channel or my twitter
https://twitter.com/gminorscalefor further updates