Why not make a game from scratch?

When I was learning C, I figured out that, because Libretro also uses C, I could simply target Libretro instead of the Game Boy Advance. Not only would this route free me of the restrictions of the Game Boy Advance but also gives me far more flexibility with what libraries and other functionality I could include (say, movies). Plus, the whole point was that I wanted to actually take advantage of the unique features Libretro has.

However, I found out that there are some good reasons why I would target the Game Boy Advance… at least at the current time.

  • Drawing graphics in the Game Boy Advance actually appears to be more straightforward compared to from scratch (even in Libretro), especially since…
  • …I only have to deal with one screen resolution (240 * 160 pixels) and refresh rate (~60 fps), whereas writing a game from scratch would have to account all of the screen resolutions and refresh rates of any device that might play my game.
  • Trying to work within the restrictions of the Game Boy Advance would lead me to write more concise, more efficient code.
  • The whole point of Libretro is that I would write a program that targets Libretro, then the program would run in any platform that runs RetroArch or similar forntends. The problem is that, in practice, I would still have to consider the different platforms when compiling. A couple examples are that, while a Libretro program would be a .dll file in Windows, the same file would be a .so file in Lignux. There is also the fact that compiling to a game platform would require a difficult-to-set-up toolchain. Keeping track of all these platforms is complex and invites significant error and confusion. In contrast, while targeting the Game Boy Advance, itself a game platform, requires a difficult-to-set-up toolchain, I have to compile to only one platform: the Game Boy Advance itself. The resulting .gba file can be played in any platform that can play Game Boy Advance games.
  • Speaking of platforms, the list of platforms that have a Game Boy Advance emulator overtakes the platforms that support Libretro. More specifically, I can also play Game Boy Advance games through native BSD, BeOS, Dingoo (along with a lot of similar devices), Microsoft DOS, Nintendo DS, Windows Mobile Pocket PC, Windows Phone 8, Windows Phone 10, and any platforms that supports the Java Virtual Machine. Then there is the obvious: I can put my game in a linker that plays the games in an actual, real-life Game Boy Advance.
  • Documentation on the Game Boy Advance, including hardware to writing homebrew, is plentiful. Documentation on Libretro development is far less so. In fact, the “go-to” tutorial of targeting Libretro is literally incomplete, unexplained in many areas, and apparently abandoned since years ago.
  • The documentation on the Game Boy Advance actually helped me understand programming using Libretro. The “pitch” (in graphics programming) and makefiles (in program compilation) were nebulous concepts until I read the documentation on homebrew of the Game Boy Advance.

There is also the fact that there is that simple appeal of playing in my actual Game Boy Advance a game that I have made myself.

 

I am still going to support Libretro directly later (maybe make a Game Boy Advance “Lite” version and a Libretro “Deluxe” version). Right now, though, I believe that targeting the Game Boy Advance would be a better next step when moving from the pico-8.

 

Advertisements

My Backup Plans

If everything goes all right, then my code at Re-Hoard should be done in 5 days of work.

Whether the code would work is another matter.

At this point, my idea is writing all of the code I can, revising the code, get my code verified, then pick between:

  • staying with Lua in the pico-8
  • switching to ChaiScript in ChaiLove
  • switching to C in the Game Boy Advance

The reasoning behind writing all of the code first then revising the code is not just because of the possibility that my problem is solvable within the pico-8 ecosystem, but also finishing the code would give me a reasonably complete framework from where I can do a translation if I do switch. Yesterday, while coding, I found that I needed to do a few new sound effects, that is, a gap that would have been more difficult in being fixed had I switched immediately to a different ecosystem.

I normally do not learn one language while using another because I want to avoid mixing up the two languages, but I let this because I plan on moving away from Lua. However, this possible mixup is the reason why I did not learn both C and ChaiScript at the same time.

I decided on learning C first. While the main motivation was simply big interest in the Game Boy Advance at the time, I found that there were more practical reasons why C would get priority over ChaiScript.

  • C is widespread. From what I have seen, C is the most widely-used language in all electronics, beating out even C++ and every dialect of BASIC together! This would make my games written in C very portable.
  • C is marketable. Because of that wide spread, a knowledge of C would be very useful in a lot of business and industrial contexts.
  • C lets me understand the hardware at a lower level. From what I had seen, C is essentially cross-platform assembly language. One of the main benefits of C is its ability of manipulating stuff at the bit level. A knowledge of C would deepen that knowledge of bit manipulation. (Once again, this deep knowledge would help me in an industrial context.) This is important because I finally would get to understand pointers, that is, a common theme in programming.
  • C helps me understand Libretro more. Libretro is a C library first of all.
  • C is reverse-compatible. My main trouble with ChaiScript is that ChaiScript ultimately relies on C++14, which would make things difficult when porting stuff to earlier hardware. This fact became more relevant here when Libretro supporting an old compiler let Libretro resume development that targets Microsoft’s first game console, the XBOX. That means that, even if targeting the Game Boy Advance does not work out, I can still code “from scratch” using an older version of C. Because I am using a book from 40 years ago even before C was standardized into C89, my code would definitely be reverse-compatible.
  • C is mature. ChaiScript is still being developed. While I am fine with waiting until ChaiScript finishes development or at least progresses to a form of maturity, C is already time-tested and, therefore, more reliable. I can write things in C while I wait until ChaiScript matures.

From another perspective, though, ChaiScript may have fit my current priorities more. The development time of Re-Hoard is easily approaching a year. Spending so much time on a simple game is ugly, even though I do not exactly have an audience. ChaiLove not only is deliberately similar to LÖVE (another framework I used) but also abstracts away a lot of close-to-hardware features. Adding assets in ChaiLove is also drag-and-drop, whereas writing a Game Boy Advance program would require conversion and appending the assets. Therefore, using ChaiScript would make a sooner release. There is also the fact that ChaiLove is tied to the Libretro ecosystem whereas making a Game Boy Advance game is not. (I could make a game “from scratch” that implements the Libretro library, but that would be too much work when the goal is getting my games released.)

Maybe I should have started with ChaiScript? I am too deep in C, but I might learn ChaiScript after I finish with the basics of C.

 

ChaiLove is a First Choice

I decided that, if I were to make my games, I would make ChaiLove my first priority.

I came along when I looked at Red, a programming language that had a simplified grammar that deploys executables in hard-to-believe small file-sizes to plenty of platforms. After thinking over the potential (if true), I wondered: why target ChaiLove or the Game Boy Advance over Red?

My answer was that I liked Libretro so much that I wanted to specifically take advantage of Libretro. I also realized that, because part of what I liked of Red was the simpler syntax, ChaiLove would be a good fit my preferences opposed to the Game Boy Advance. In fact, the only real advantage I have in targeting the Game Boy Advance, other than being able to play my games in the Game Boy Advance SP I have, would be protection against the possibility that ChaiScript, due to its eventual reliance on C++11, would not make games that would run on old platforms… or the 3DS or PSP.

I would still explore Game Boy Advance development due to the accessible knowledge of low-level programming, the still widely-used C language, and having an available backup if my worries on the portability of ChaiScript come true, but ChaiScript’s mixing strength with ease of use (a big asset to me) had bumped up ChaiLove’s place.

Libretro multiplayer

Recently, Raidus is putting netplay that works with the Game Boy and the Game Boy Color. The functionality even works with different games, which would make Pokémon multiplayer actually functional! This is a change from the way Libretro once did things!

This would radically change my game plans.

  • If I decide to make a game “from scratch,” then I would not have to worry about using an external library when making my game. (I hope that I can still make a type of Pokémon Communication Center, though, which would mean that I would make a separate but related game that is supposed to be a server instead of a client.)
  • If I decide to target ChaiLove, then I feel more comfortable in how Rob Loach’s implementation of networking would turn out. This may complicate things on his end, though, because he is the one implementing the API.
  • If  I decide to target the Game Boy Advance, then all I have to do is implement functionality of the Game Link Cable and let Libretro worry about implementing the actual functionality!

In all, thank you so much, Radius!

ChaiLove or Game Boy Advance

Summarizing part of my pathway in game development, I was initially excited in developing games in LÖVE and the pico-8. However, I hit into the deficiencies of Lua… mainly how Lua does not have support of classes. Because of this, I spent my time searching for alternatives. Two platforms ended up fitting my needs: ChaiLove and the Nintendo Game Boy Advance.

To me, ChaiLove is LÖVE without the problems. More specifically, ChaiLove retains LÖVE’s ease of programming (and, in fact, is modeled after LÖVE’s API), flexibility in programming, abstraction of lower-level requirements (rendering graphics being the big one), and freedom from compilation while adding the benefits of C++/ChaiScript (actual classes!), taking advantage of Libretro, and meaningful active development. In fact, the Libretro blog post explicitly mentions potential portability to other consoles because ChaiLove targets Libretro!

Before ChaiLove appeared, though, I seriously considered using a more indirect approach in trying to write a “universal” game. In this case, instead of trying to code from scratch a game that works in every platform that RetroArch supports, I could simply look for a game system that every version of RetroArch can emulate, then write a game that targets that system. This approach also provides (theoretically) infinite forward-compatibility. Though I initially considered this approach because ChaiLove did not yet exist, the fact that ChaiLove depends on ChaiScript, which depends on C++14, motivated me towards considering the indirect approach again. After all, Visual Studio 2003, which is the latest compiler that can generate binaries that work with Windows 95 and the original Xbox OG console (the one before the XBOX 360), does not support even C++11… or C11, in that matter.

After currently comparing the systems that Windows 95, the Nintendo 3DS, and the PlayStation Portable can play, I decided that the best system was the Game Boy Advance. My reasoning was that:

  • I should avoid any emulators that prohibit commercial use (an issue that plagues Libretro and its contributors to no end)…
  • …or anything that requires an official BIOS.
  • My theoretical game Wuu Shyng is based on the mainline Pokémon series, which is played in the handheld GameBoy and DS product lines. A result of these game being played on handheld systems is that the contents of two different save files interact with each other; home systems that use save files usually rely on the contents of only one save file, instead.
  • My games are based on a maximum of 3 action buttons and 1 menu button. A lot of the systems that Windows 95, the Nintendo 3DS, and the PlayStation Portable can play use 2 action buttons and 2 menu buttons, instead.
  • While I could target the original Game Boy or the Game Boy Color systems, I read, repeatedly, that games that target those systems needs to be written in Z80 Assembly language, even when C compilers exist.
  • The Game Boy Advance has a lot of strength. Mario Pinball Land used 3D graphics. The Game Boy Advance Video series used full-motion videos.
  • The games I want to make are essentially Super Nintendo/Game Boy Advance games, anyways.

Targeting the Game Boy Advance is a very different paradigm, though. I have to code the game in C instead of C++, which uses structures instead of proper classes. The Game Boy Advance does not play actual audio files, but, rather, MIDI-style files that say what sound samples should be played. (I am not good at making full songs, plus there seems to be a lack of freely-licensed music that can be played in the Game Boy Advance.) Sprites have to be converted to bits (which was a big problem when I looking into coding a game from scratch). Homebrew information on the Game Link Cable (a big thing, given Wuu Shyng and its influence from Pokémon) is rare; homebrew information regarding the Wireless Adapter (something that would be very beneficial) is even worse. Of course, I would have to compile, though I would also have to use a toolkit (in this case, devkitARM, a part of devkitPro). Finally, the Game Boy Advance, being a dedicated handheld device, has more programming restrictions… a lot of them.

However, from what I see, targeting the Game Boy Advance is within my skill set. I mean, the Tonc guide and devkitARM’s libgba libraries seem to make the Game Boy Advance accessible. I have the 1st edition of The C Programming Language, a book that is not only enjoyable and digestible but also would definitely produce C that is compatible with Windows 95. Use of C also means that I, in theory, could use plenty of the C libraries out there that would help my game development. I would not have to worry about different display resolutions because I would only have to focus on keeping things 240 * 160. Implementing multiplayer through either the Game Link Cable or the Wireless Adapter bypasses Libretro’s current netplay system which is opposed to the way I want to make multiplayer, which is based on handheld game systems, anyways. (I would still have to do something about programming a server because I want to implement a type of Pokémon Communication Center in Wuu Shyng.) Game Boy Advance games (excluding a couple of Game Boy Advance Video cartridges) go up to 32 Megabytes, that is, significantly small by current standards. (Thought the main influence on file size comes from the programmer, getting a maximum file size, especially one that small, is comforting to the downloader.)  There are also more platforms that can play Game Boy Advance games… including the Game Boy Advance SP that I currently have.

Honestly, I am actually getting excited from the possibilities. I am eager in getting Re-Hoard and Reckless Abandon done!

Chai Chai Chai

ChaiScript is a new scripting language more directly based on C++. That means actual classes and stronger overall capabilities.

ChaiLove is essentially LÖVE with ChaiScript. LÖVE has spoiled me with its mature functionality and many user-provided libraries, but ChaiLove actually seems complete.

 

This puts me at a crossroads. In one thing, ChaiLove combines LÖVE’s ease of use and freedom from compilation with C++’s functionality. On the other hand, ChaiScript requires C++14 since version 6.0.0, which was previously C++11 since version 5.3.0, which was Boost up to version 4.3.0. Stone Soup got those problems with C++11 being too new to old compilers, making my “a game that runs in any platform that runs RetroArch or even just Libretro” difficult.

I shall keep an eye on ChaiLove, but I am not permanently switching from my plans of making a game “from scratch”.

Wrapping up the game package

I think I got together all of the pieces of game-making.

Compilation: From the start, the compiling tool was going to be make, which was simple. (Compiling a Libretro core only needed “make -f Makefile.libretro” or even just “make”!) CMake was too complicated, while Bazel needed the horribly insecure Java. The actual compiler I would use was Clang on top of LLVM. My reason is that LLVM/Clang seems to be compatible with projects that work with GCC, the standard of compilation in C, but brings its own benefits, including keeping closer to the original code in compilation while managing better performance. I am new to makefiles or actually knowing compilers, but I found this tutorial which makes things look actually possible.

Networking: Though Libretro has netplay, there are at least a couple of problems with their current implementation.

  1. The way Libretro’s netlag-hiding works is that, during netplay, Libretro constantly makes savestates. If the savestates of the players are out-of-sync, Libretro loads the last savestate when they were in sync then continues normal gameplay. Notwithstanding that any core I would make would have to support savestates which themselves require serialization, the savestates have to be a certain size, meaning that even Nintendo 64 and Playstation 1 emulators cannot use netplay.
  2. Libretro’s netplay seems to be modeled after a home console (multiple players playing on the same system that runs one game) instead of a handheld (multiple players using their own systems that run their own games and connect each other in some way). Driving home this point is the Libretro crew specifically saying that you cannot trade Pokémon through netplay. This is a problem because one of my games Wuu Shyng, is a spiritual successor of Pokémon. Netplay is, therefore, a big concern with me.

While the FAQ list implies that the Libretro crew is going to make a new form of netplay, I decided that the better option would be to not use on Libretro’s netplay at all and instead use an external library, though I would take cues from Libretro’s implementation of netplay in anticipation of compatibility with any future implementation that may work with me. After browsing the Awesome C(++) list for network tools that use TCP (the protocol that Libretro uses), I decided that Mongoose was the best option due to its small size, ease of implementation, and, most importantly, ease of use.

Cutscenes: I decided from the get-go that the files are going to be .ogg files that use Vorbis audio and Theora video, both of them being open-source standards of lossy audio/video. (I could use lossless formats, but I want to keep my games small, especially when you consider that Retroarch has been ported to the PSP and 3DS.) Actually playing those videos is another matter. While I initially looked into using the libraries themselves, their complication combined with my need to implement subtitles (.srt files, by the way, because they are easily written) and the possibility of me needing to add more features led to my decision to just integrate MPlayer in my game. MPlayer has a “slave mode” (ew) that makes this possible. The controls look great; I think that I can have player control the video through their controlers. The one thing that bothers me here is that there is no way of doing a frame-step backward. After looking into how that mode works, I decided to simulate a frame-step in either direction by telling MPlayer to rewind or fast-forward by a fraction of a second, that is, how long does playing a frame take.

Frames Per Second Seconds of a Single Frame
25 0.04
30 0.033333…
50 0.02
60 0.016666…

The small, finite numbers, combined with how much less work would manually animating things be, led to my decision to make files at 25 frames per second. That suits me just fine; I actually do think that PAL, the European analog television system and source of the 25 fps standard, is “Peace At Last”!

That being resolved, my only real issue here is how I would get MPlayer to display to either SDL2’s SDL_Surface or Libretro’s video_cb, unless MPlayer already takes care of that. If I resolve that, then I finally have a complete framework from where I can make Libretro games free from Lua.

SDL, too!

Despite my deciding to give up on trying to make graphics work using just Libretro, I keep coming back to the subject.

There days, I searched again for how Libretro cores that were not emulators displayed graphics. I hit upon the answer in NX Engine, a core that also seems to have a version for every platform that RetroArch is built for. More specifically, NX Engine’s video_cb (the framebuffer that Libretro uses) is a SDL_Surface that holds the pixels. I ended up giving SDL2 a more serious look. Honestly, SDL2 seems to be easier to use than I thought, being on par with my experiences with LÖVE. I can even do basic collision with this! Using SDL2 also solves the problem with using audio and working with files. (Though SDL2 also gives user input and rumble support, I prefer using the Libretro functions themselves.) All that remains is how to add network support and use make.

I also looked at other game engines and frameworks that probably had what I needed. SFML was the best match, but I needed to convert its RGBA8888 format to ARGB888 format first before I use a couple of Libretro’s functions in converting to RGBA4444, then RGB565. Thankfully, the code to convert from ARGB8888 to ARGB4444 seems to be easily modified to accept RGBA8888, instead.

I am still leaning towards using SDL2 if I ever make a game here without LÖVE, though, especially when I consider my lightweight goals.

SDL2 Targeted at Libretro?

The desire to find a way to handle graphics directly in Libretro came up again since about a couple of weeks ago.

I ended up at several venues of possible solutions, one being sdl-libretro. My big issue with trying this is that the repository uses SDL 1.2.15 when SDL2 already exists. After looking at the code, I made a folder that had the include, src, and test folders of the SDL2 source and the Makefile.libretro file of the sdl-libretro repository.

The compiler wanted EGL/egl.h . I ended up adding EGL, KHR, and X11 (actually a combination of X11 and XProto sources!) folders before the compiler requested sys/syscall.h . A search revealed that sys/syscall.h does not exist in Windows, the operating system I am using now. I temporarily modified the Makefile.libretro file by adding:

platform := win

after line 13 in the file. I also renamed the naming scheme from “SDL” to “SDL2” because I wanted to differentiate my experiment with SDL2 with the official sdl-libretro repository.

I ended up with a libSDL2_win.a file.

I am surprised and relieved that compilation apparently works, but what am I supposed to do with this file?

 

P = NG

After my previous adventures in rendering .png files to a software framebuffer, I realised that I needed to convert between lodepng’s RGBA 4-bits-per-pixel format to Libretro’s RGB565 format. My studies since my last post brought me to pixconv.c which has a function, conv_rgba4444_argb8888, that does just that type of conversion. I need to give the function the following in this order:

  1. the output variable
  2. the input variable
  3. the dimensions of the image file
  4. the output pitch
  5. the input pitch

In theory, all I had to do was add lodepng and pixconv.c to my project, run a test.png file through those two, and put the resulting data in the framebuffer.

The result was a mess. Learning that <iostream>, a stape at my studies of C++, was worthless when working in C, was actually the easy part. Even if I did not exactly know what type of data type were the variables that held the RGBA4444 and RGB565 arrays (I settled on unsigned char when void did not work), the makefile refused to recognize lodepng_decode32_file and logepng_error_text, even after I put those two types in various places (though not at the same time) inside the actual libretro_test.c file. I learned that this issue comes from the linker, which is related to the makefile.

At this point, I decided to give up at least temporarily. I mean, while there is the possibility that this is the last problem and that I actually have everything else right, I decided that this matter requires advanced knowledge that is specialized on C++. I mean, I have a Master’s Degree in Software Engineering, but my actual usage of the fundamentals of C++ and related languages were all in Integrated Development Environments. I barely know anything more than how to run make (not “CMake”, but “make”)!

This lack of specialized knowledge is also the reason why I am no longer pursing either adapting a current C++ engine to Libretro or, per Radius’ suggestion, using OpenGL. I still would have to deal with compiling the C++ code in those situations.

In light of this, I was looking more seriously at Rust, which has bindings to Libretro. While Rust is not object-oriented in the conventional sense, Rust has features that have just about the same functionality anyway. The problem is checking how the current game engines that use Rust render graphics. After all, I want to use software rendering because I want my games to be played at the full range of consoles that run Retroarch, not just the ones that can handle both versions of OpenGL.

I am also seriously considering going back to Lua per my original plans. Not only does LÖVE have no need of a distinct compilation process but also displays graphics through an API that works great and easy. In fact, the ease of use LÖVE provides is the reason why I picked using LÖVE instead of straight C++ in the first place! The main reason why I am not so sure is because that the reason why I wanted to leave Lua in the first place was because Lua did not have any proper support of object-oriented programming. I would much rather use the real deal, especially since Re-Hoard needs object-oriented programming! Even if there is an alternative, this lack of functionality may hamper heavily my plans of future games!

I tried to see how Lutro, Libretro’s interpreter of LÖVE, displays games written in LÖVE. I mean, LÖVE apparently uses SDL, but that does not seem to be a problem to Lutro. However, I got overwhelmed once again.

Eevee is right; if I were to write from scratch, I would be essentially inventing the universe if I needed to get off the ground. Then there is compilation afterwards.