Name: | Smalltrek |
---|---|
Version: | git |
Author: | impbox |
License: | MIT |
Operating System: | Linux, Mac and Windows |
Nim?
To promote adoption of Gamerzilla, I've been spending more time on IRC. Someone on freenode's #gamedev channel mentioned Nim. The discussion wasn't about a game but I wondered if there might be something interesting to look at for Open Game Source.
Nim aimed to be efficient, expressive and elegant. It took ideas from many languages like Modula 3, Delphi, Ada, C++, and Python. It compiled to multiple targets languages. I used the default C target but it can target Javascript to deploy on a website.
Several games were suggested to me. The web version of Smalltrek impressed me. Unfortunately Fedora had Nim 1.0 not 1.2. The Nico module used by Smalltrek required 1.2. Rather than fight with it, I tried Glorious Glacier Grotto. The game used Nimgame2 which didn't have working menu but I could run the game.
Smalltrek continued to call to me. Trying to rebuild Nim rpm with the latest version failed on some test cases. Eventually I installed Nim 1.2 from nim-lang.org. Smalltrek failed to compile.
Minor Fixes
The Nim language was not remarkably different than other languages I'd dealt with. I felt comfortable without needing to read a long tutorial. I did turn to the IRC channel a few times. The community was quick and helpful.
The small compile errors were easily fixed but the game didn't play as well as the web version. In the web version when you move to the right, the planets moved at different speeds to the left. At the edge of the screen, they would wrap around to the other side. The native version had all the planets disappear off screen.
The planet's x position being modded by 128 but nothing prevented it from becoming negative. Adding 128 to the position before modding fixed the problem. The y position had a similar problem.
The game said to use Z, X, and C keys for buttons but the X button didn't work. Nico supported an Xbox like controller scheme. The key for the X action was the "X" button but Nico configured the use of left or right shift for keyboard controls. The "B" button was configured to the X key. Not sure whether the instructions or code should be updated.
Pico-8 API inspired the design of Nico. While I had Pico-8 on my PocketChip, I never really explored the API. Documentation on the config functions were missing which was annoying during later work. It claimed to support a 256 color palette. Not sure what would happen if a sprite or drawing function attempted to use a color not in the palette. Multiple sprite sheets could be loaded but you don't specify the sprite sheet when drawing. You must set the active sprite sheet before drawing.
The typical game loop was performed by nico.run. It took an init function run once, an update function, and a draw function. The update function received the time delta from the last run. It defaults to running at sixty frames per second if it can. That can be adjusted with the nico.fps function. Overall the API seemed usable.
New Species
While I didn't implement any, I did look at adding a new species to the game. The biggest piece would be to update the isHappy function. That controlled the logic to determine if the alien is happy.
One thought was to create a "Mirror, Mirror" version of the game. Every world would start at 100% happiness and you needed to destroy that. Should the existing aliens be used or new version? Moving a Botarni away from a plant might be easy but if it needed to have line of sight to the plant blocked that might be more interesting but my major goal was adding Gamerzilla support.
Gamerzilla Support
LibGamerzilla was written in C because languages typically provided some means to interface with it. Originally LibGamerzilla had the developer fill in a C structure with information about the achievements. That proved difficult but not impossible to use with Python. The latest version added GamerzillaSetGameFromFile which allowed everything to be read from a json file.
Nim had very good integration with C libraries. I created a small nim file that defined the interface for Nim and specified the C function to call. For example, the GamerzillaSetGameFile took two const char * arguments and returned an int. The declaration in Nim was:
proc setGameFromFile*(filename: cstring, datadir: cstring): cint {. cdecl, importc: "GamerzillaSetGameFromFile", dynlib: GAMERZILLA_LIB.}
The library file was specified but to my surprise was not linked to the application. The library was loaded dynamically. Which meant that when packaging a Nim application on Fedora, it will not automatically detect dependencies.
Before I started playing around with Smalltrek, I looked at adding Gamerzilla achievements to SuperTuxKart. SuperTuxKart already had achievements so it would simply require hooking it up to Gamerzilla. For Shippy 1984, I added calls to set achievements in various places. SuperTuxKart instead collected all the stats and then checks achievements in one place.
For Smalltrek, I followed a similar setup. That way it was easier to add a define which enabled Gamerzilla support. Project maintainers could be hesitant to add another dependency to their project or they might not be able to do so for a javascript backend. Gamerzilla was enabled by default for Linux and Windows. I believed it could be built easily for MacOS X but had not done so yet.
Smalltrek didn't have achievements. The simplest achievements would be for completing each quadrant in the game. That sort of reward for completing the game was great but trophies were meant to reward activities beyond those required to win the game.
The Cuwudle species could be killed by the Cardak. I wiped them out once because that would ensure everyone was at 100% happiness. The game didn't allow that to succeed. Eradicating a species caused the mission to fail. To commemorate this, I added the "You Monster" achievement for the action.
Of the levels I completed locally one took 44 moves which was probably pretty bad. I created a "Rearrange Chairs" award for anyone who took more than 45 moves. Since there was no chair in the game, I used a chair from opengameart.org and modified it to closer match the style of Smalltrek. For this game, the achievement not unlocked are the same image as unlocked achievement converted to grayscale and brightened some. You could use completely different images if you choose or a single image for all locked achievements.
While not currently implemented, you could store the number of failures for a level and give a persistence award. Each level could have a par value for moves and if you got some or all below par, you got an award.
Comments
No comments yet.