Hello! This article is a tale about how I decided to write a game 6 days before the New Year, how I did it, what problems I faced and how they solved them.
7 days ago (at the time of writing this article) I needed to develop a game, so much so that I could meet the deadline before the New Year (there were 6 days left). As planned, the game was supposed to be a 2D platformer in the New Year theme, for two on one screen, for a PC, with only one, but a long level, during which the players had to go through the actual platformer and puzzles. It's not entirely clear what “platformer itself” means? Let me explain: the game had to consist of 20 parts, successively following each other, 10 of which were “sets” of platforms, enemies, spikes and other things - “platformers proper”, and 10 others - platformers puzzles, in which players had to Solve problems to advance the level further, that is, as in the picture below:
Instruments
I didn’t have time to write a game from scratch on the “bare”, besides, it was conceived in 2D, so my choice fell on
Game Maker: Studio as a convenient and quite simple engine, where you can quickly start developing games . I already had experience with this wonderful tool, so I did not hesitate to download the slightly outdated free Standart version and continued further training.
')
I have a doublebut on my computer - Ubuntu and Windows, I
almost always work on Ubuntu, but since GM: Studio for Linux does not exist, I had to switch to Windows for a while. And since I do not work on Windows, my system (in terms of software) is almost naked. I didn't want to download Photoshop, so I had to paint all the graphics in Paint.NET
(put the tomatoes in place) . It is important to note here that I decided to start working with graphics, as from the most unpleasant part for me - and was defeated: I didn’t really draw. And then I decided to start with the code, using not sprites in the game, but stubs - multi-colored squares and rectangles, and at the end, when the code and level are ready, draw and put graphics into the game.
Of course, I am not a composer, and I did not even try to make the sound part of the game myself, but decided to use royalty-free music. I downloaded several tracks and proceeded to the next part.
Game design
A lot of people think that a platformer is an easy genre to develop. Personally, my opinion: there are no simple genres to develop. And if you still have - then certainly not a platformer. But why am I? A large part of the work in developing the game is
what I was convinced of in my own skin , in thinking through the levels, and this is not at all easy. For this I needed a notebook with a pencil and a little time. During the first two days, I worked on the parts-plaformers and parts-puzzles, while designing some of the quests so that they had to go through together.
I also paid a lot of attention to the next problem: it would be boring for players to play if they hadn’t come across anything new for all 10 platformer parts. Therefore, for each part of the platformer, I invented one new game element: a new enemy, lasers, moving platforms, platforms that either disappear or appear, mini-bosses, the main boss, and so on.
As I said above, the game was supposed to be one big level, but, as always happens, after creating the first 2-3 parts, I had the good fortune to watch the rapidly falling FPS, which is why I decided to divide the game into five levels of 4 pieces (2 platformers and 2 puzzles) for each. As a result, the total length of all levels turned out to be about 30,000 pixels, with a character size of 36x58. And also I decided to make the 0th level - the level where the players would be trained by demonstrating the basic game mechanics.
And now a list of what I wanted to implement and implement:
- Spikes - objects, in contact with which the death of the character takes place and the revival on the last checkpoint
- Checkpoint - a place where the player maintains his position, securing the passed part of the level
- Moving platforms - platforms that can move horizontally / vertically, while transferring the player standing on them
- Buttons - for opening doors, etc.
- Levers - the same as the buttons, but have the state - on / off.
- Doors - in the closed state do not let the player through, in the open state - they let through
- Laser - works with a certain frequency: it turns on / off, when the state is on and in contact with it, the character dies
- Box - players can move it, when moving it to the button it activates it
- Unstable platforms - platforms that disappear / appear with a certain frequency.
- Teleport - Teleport A teleports the player to the teleport B position
- Fireworks - to shoot down flying enemies
- Snowballs - to destroy the mini-bosses and the boss
- Several (6) types of enemies
I also wanted to do the following, but later refused:
- Non-Jump Platforms
- Platforms on which you can not stand for long
- Stairs
- Air flow
I implemented most of this at the same time as the training level. And now a little about the code.
Programming
Despite the relative diversity of the game, it did not contain a lot of code: according to my immodest calculations, ~ 1400 lines. Basically it was the code that sets the behavior patterns of the enemies, as well as the code relating to the control of the character.
A little about management. It was assumed that the first player will play on the keyboard, and the second - on the gamepad (since the game was designed as a gift for my friends, it was so). GM: Studio has excellent gamepad_ * functions that refused to work with my device, so I had to use the good old joystick_ * functions. And everything would be fine, but when I got to the moment of programming the behavior of the lever, namely activating this behavior with the gamepad button, it turned out that the function that checks whether the button is pressed (joystick_check_button ()) is not enough, since it only checks if it is pressed whether the button
now . And since the user is not able to press for only 1/30 seconds (1 game beat in GM: Studio by default), it turned out that he pressed the button many times, which made it very inconvenient (even almost impossible) to set the lever in a certain position. Therefore, I had to write my own function, which, in addition to checking for pressing a button, also checked whether it had been pressed during the last 0.8 seconds.
Directly controlling the player included only moving left / right, jumping, activating buttons / teleports / levers, throwing a snowball and launching a firework.
At the beginning of the development (on the 0th, 1st and partially 2nd levels) there were problems with the initialization of quests and some game elements. It was necessary to create an initializer object that contained a code that sets certain variables of certain objects to certain values, for example, the code that initializes the button in position (7256; 564) looked like that at the opening of the door (7661; 520) :
with (instance_position(7265, 564, obj_button)) { // task_x = 7661; //, X task_y = 520; //, Y }
Later,
in one happy moment , I discovered a useful feature of GM: Studio, namely the Creation Code. As it turned out, right in the room editor it was possible to specify the code for a specific object instance that would be executed immediately after the instance appeared in the room, and the same initialization began to look like this:
task_x = 7661; task_y = 520;
Also, the minus of the approach with the initializers was that they had to appear in the room after all the objects they initialized. For this to occur to me, it took half an hour to peer at 4 lines of code and look for an error where it was not there.
Another problem with initialization was that after loading sprites with dimensions, for example, 22x11 and the absence of filled pixels in the upper lines of the picture, GM was
too clever : Studio cut off their masks (“silhouettes” of the objects on which the collision is checked) to the first line with nonzero pixels. And since during the initialization of the object in the target position I indicated the coordinates of the upper left corner of the object, then an attempt to detect there any instance could not be crowned with success, because the mask was a little lower! I had to change the type of masks of the necessary objects from Auto to Full Image.
Graphics
As I said, I painted in Paint.NET, and despite everything, it’s not so bad. Yes, there are unusual for me and therefore annoying aspects of working with some tools, but, in general, everything is quite convenient.
I painted in the style of Pixel-Art, but since I, say softly, far from being an artist, it turned out something like this:
I drew all the graphics on the last day. When placing tiles in a room, the Add Multiple function, which is activated by pressing Shift and simultaneously pressing the LMB in the room editor, in the tile editing mode, helped a lot.
It is also worth mentioning that all the graffiti (for puzzles) also made tiles.
He first painted the background himself, then asked a friend of the artist to redraw it. What was / was:
Sound accompaniment
I mentioned above that I decided to use royalty-free music and downloaded some tracks I liked, but in GM: Studio there are no functions that can play around a “playlist” of several tracks, so I had to write everything myself. Subsequently, it turned out that I was somewhere “slightly” flawed with synchronization, so after playing the first track, several more were played at the same time, but these are all the consequences of not having much time.
Yes, it worked all, probably, problems on the client side.I also wanted to add sounds to the game (pressing buttons, opening / closing doors, enemies), but a day or two before the “deadline” I realized that I wouldn’t have time - I had to refuse. The problem was not even that it took time to insert sounds into the game - time was needed to find them.
Managed?
I finished writing the code and completed the last quest 20 minutes before the chimes. But something I still did not have time:
- Level 4 had to be thrown away: did not have time
- Level 5 had to be cut a little: I threw out the second quest
- During the passing of the game, which I attended, two
two were caught , Karl! crashing on quests: I didn't manage to retest everything - Animations - characters and enemies are static (although in the resolution for which I adapted the game, this is not very noticeable)
- Do not have time to draw a sprite of hearts, showing the life of the character - they remained squares
- Minor flaws in the form of somewhere not placed tiles, tiles not on that layer and invisible moving platforms, in which I forgot to initialize the sprite_index and visible variables
Conclusion
Of course, serious games are not developed in 6 days, but, as it turned out, if you try very hard, you can create an
almost working, playable alpha in such a short time.
Download the game (this is not advertising, just some people wanted to touch the game with their own hands), please follow this link:
Google DriveIn fact, this is not exactly the game that I wrote in six days. This version had to spend a few more (7-8) hours. Management: WASD, the rest is inside. (The control is also on the arrows + space, but it is better not to use them).