Ludum Dare 42 – Closing in on Pascal

The game jam for August was Ludum Dare 42, so with it coming to a close, I thought it’d be good to talk about how the submission [Closing in on Pascal](https://ldjam.com/events/ludum-dare/42/closing-in-on-pascal) came about and what I learned from it.

Ludum Dare 42 was particularly exciting for me, as it was the first LD in a long time that I had a completely free weekend. As such, I decided to plan the first day entirely for gameplay, with graphics and audio on the second day. That way I get a solid game and then plenty of time to work on making it look and sound nice, you’ll find out why that plan isn’t flawless as it sounds.

When it came to the theme, I was already very pessimistic that it would be a theme I’d be happy with, it’s been a common trend for people to vote on the theme that no one wants. I even voted against the theme “Running Out of Space” but when it turns out to be the chosen one, I thought it was pretty good.

The concept of running out of space I had was inspired by the cartoon trap of the walls closing in on someone in a temple. I figured a game where the player has to reach an exit before the room crushes them to death.

Fortunately, I have a bit of experience with platformers in my game engine from a previous jam, so the tilemap, jump physics and mechanics such as wall jumping I have previously implemented.

LD42-00000.gif

The jump animations itself was done because I remembered the indie platformer INK having good squash & stretch. To achieve it I modify the scale so that it squashes inwards when going up and stretches outward. If I had more abilities to adjust the individual vertices I could do more fun aspects of moving like skewing.

LD42-00001.gif

Since my idea was inspired by a temple film/TV trope, I already had the visual theme in my mind. I also thought it would be good if I had a little cartoon character who’d look like Indiana Jones. It was fun working with pixel art and animation once again, but if I was to do this again I would have done a much simpler approach. The player character is way too small for the game screen, meaning that its animations are pretty much useless. I also had a bit of issue with making the colours stand out so it doesn’t feel all yellow and brown.

LD42-00002.gif

In the end, it took around 3 – 4 hours to work on the background environments and 5 hours to work on the player sprite and all the obstacles. If I went with a much simpler design or scrapped the temple theming and used the simple colours and shapes it would have been much clearer and easier to look at.

LD42-00009.gif

The sound and music was achieved with LMMS and BFXR. I like making NES-like chiptune in there but I do notice it’s restrictive in areas like tones and tempo, so I couldn’t get the sounds I want. It also didn’t help that thanks to the graphics, I had much less time to work on sound and music so it ended up rushed.

The post-jam has most of what I would have added or done better if I had time. Particle effects, using directional keys as well as the WASD buttons, and a better title logo. I would have also worked on more levels but seeing how many levels players are willing to go through, then maybe the existing levels should have been improved slightly.

I’m a little worried about what the rankings will be for this one, I’m definitely glad I could take part but I feel as though I wasted too much time on the graphics when a simpler approach would have been effective. You can go check out [Closing in on Pascal](https://ldjam.com/events/ludum-dare/42/closing-in-on-pascal).

Advertisements

Games on Command: Making of PEWBALL

For the month of July, I decided to take part in Floppy Jam as my games jam for that month. Floppy Jam was a small jam with a novel idea, make a game that could fit on a single floppy disk with the total memory capacity of 1.44 MB. I decided to take part but there is an issue, most of my typical development environments could not make a game that small, even if I made a completely procedural game. So I decided I should make a new engine, where it has the most basic elements (graphics, sound and input) in its smallest possible code. That’s when I decided to make a games engine using the command prompt.

 

The command prompt looks simple, there isn’t much you can output to the console and it’s typically slow, at least not fast enough for real-time smooth rendering. However, that’s if you use the standard iostream or stdio functions. The Windows library actually treats the console window like any standard window, with a handle for both input and output, as well as a screen buffer.

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;

GetConsoleScreenBufferInfo(hConsole, &csbi);

SMALL_RECT rectWindow = { 0, 0, 1, 1 };
SetConsoleWindowInfo(hConsole, TRUE, &rectWindow);

COORD coord = { (short)SCREEN_WIDTH, (short)SCREEN_HEIGHT };
SetConsoleScreenBufferSize(hConsole, coord);

SetConsoleActiveScreenBuffer(hConsole);

It is possible to resize the window by shrinking the screen buffer to the smallest possible size, before scaling it up to the size you want. Frustratingly you cannot set the console to any size you want, as there appears to be a restriction that the size cannot be larger than 800×600 pixels. For the game, I ended up using 108×60 characters to make the game the largest widescreen resolution. You can also set the font and the font size, the window title and window position as well, which is enough customization you need even if it’s not possible to get fullscreen or “high resolution”.

Input can be read from the input handler, including focus, mouse and keyboard events. You can also use GetKeyAsyncKeyState() to get real-time input handling. Mouse positions can only be accessed from the input handler.

HANDLE hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);

INPUT_RECORD inBuf[32];
DWORD events = 0;
GetNumberOfConsoleInputEvents(hConsoleIn, &events);
if (events > 0)
	ReadConsoleInput(hConsoleIn, inBuf, events, &events);

for (DWORD i = 0; i < events; i++)
{
	switch (inBuf[i].EventType)
	{
	case FOCUS_EVENT:
	{
		windowFocus = inBuf[i].Event.FocusEvent.bSetFocus;
	}
	break;

As mentioned earlier, using standard text input/output isn’t fast enough for real-time rendering, it’s also rather limiting. What we need is a way to render a full array of characters to the console screen, so how do we do that? And how do we display colour? Well, the best way deals with both birds with one stone, WriteConsoleOutput(). This function writes a full set of characters to the console, but you do not input strings, but a special Character format that allows you to set either ANSI or Unicode Characters, as well as what foreground and background colours for that element in the array. Command Prompts (as well as most pre-installed terminals) give you a maximum of 16 foreground and background colours each, although with the right character sets and other tricks you could create more colours. Once you have set up an array, you just call WriteConsoleOutput, using your console output handler, the array, the size of the array in width and height as well as the area you wish to draw to. A lot of this info I first discovered from the One Lone Coder through his ConsoleGameEngine tutorial series, as well as a header-only roguelike engine called rlutil.

///Buffer Screen
CHAR_INFO *bufScreen;

void drawChar(int x, int y, short c, int color, int bgColor = 0)
{
	if (x < 0 || y < 0 || x >= SCREEN_WIDTH || y >= SCREEN_HEIGHT)
		return;

	bufScreen[y * SCREEN_WIDTH + x].Char.UnicodeChar = (short)c;
	bufScreen[y * SCREEN_WIDTH + x].Attributes = color | (short)(bgColor * 16);
}

///Drawing the full buffer screen array to the console.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleOutput(hConsole, bufScreen, { (short)SCREEN_WIDTH, (short)SCREEN_HEIGHT }, { 0,0 }, &rectWindow);

///Clearing the buffer is as simple as setting all the elements to 0.
void clearScreen()
{
	memset(bufScreen, 0, sizeof(CHAR_INFO) * SCREEN_WIDTH * SCREEN_HEIGHT);
}

For timekeeping, an easy way to get efficient time tracking would be to use the standard library chrono. However, to avoid overhead and allow support with older systems, I needed a more specialised solution. Fortunately, I remembered a Windows-specific method of timekeeping from a video by a game developer going by the name TheCherno. While in more recent videos he recommends newcomers to use chrono, in a C++ game engine tutorial he used QueryPerformance functions. Essentially, you call QueryPerformanceCounter(), which will return you a timestamp accurate to the nearest microsecond of the PC’s performance counter. You can get the timestamp from the start of your loop, and another at the end to work out the total time to process a loop. While it is platform specific, because it’s part of the Windows API there is little overhead, and it’s extremely accurate.

bool StartCounter()
{
	LARGE_INTEGER li;
	if (!QueryPerformanceFrequency(&li))
		return false;

	PCFreq = double(li.QuadPart);

	QueryPerformanceCounter(&li);
	CounterStart = li.QuadPart;
	return true;
}

float GetCounterNanoseconds()
{
	LARGE_INTEGER li;
	QueryPerformanceCounter(&li);
	return (float)((li.QuadPart - CounterStart) / PCFreq);
}

float GetCounterMilliseconds()
{
	return GetCounterNanoseconds() * 1000.f;
}

Finally, for sound, I only wanted the simplest implementation I could find. All I needed was the ability to load Wav and Ogg files, and play them in parallel. Fortunately, that is possible with a single library and a header file. Randy Gaul developed a large collection of self-contained systems, each could be used with a single header. This included cute_sound, which does exactly what I wanted. It does have some minor faults such as crashing if you tried to delay a sound, and needs a significant updated to be friendly with modern compilers because of how it uses goto statements, and unfortunately because of how the Vorbis library works you cannot make it header only, but it’s not complex.

void loadAudio(const char* name, unsigned int id)
{
	freeAudio(id);

	const char *dot = strrchr(name, '.');
	if (!dot || dot == name) return;

	if (!strcmp(dot, ".ogg"))
		load_sound[id] = cs_load_ogg(name);
	else if (!strcmp(dot, ".wav"))
		load_sound[id] = cs_load_wav(name);
}

void playAudio(int id, bool loop, float volume, float pitch, float pan, float delay)
{
	cs_play_sound_def_t def = cs_make_def(&load_sound[id]);
	def.looped = loop ? 1 : 0;
	def.volume_left = volume;
	def.volume_right = volume;
	def.pitch = pitch;
	def.pan = pan;
	def.delay = delay;
	cs_play_sound(ctx, def);
}

The engine’s structure is that the user simply defines preprocessors for constant values, and includes a single header to get the engine’s full functionalities. All they need to do is to set up a function for handling updates and rendering (if they want to use real-time functioning) or event handling, and then call a function called run to start the engine. Keeping it like this basically means it’s possible to create tiny demos and games with whatever external tools they want.

When the jam actually started (yes I built a two-header library about a week before the jam began), I wrote basic state management system for the two scenes I wanted (title and game), as well as renderable objects. Each interactable object used a game object struct that had basic physics for movement and collision checks. The pinball environment was achieved by assigning each wall an ID, and that ID also corresponded with the angle of the slope as well as how it appeared. While most other game objects were defined as sprites, an overridden game object that has an array to represent a single static image, the flippers was a special sprite that manipulated that array based on how long a button was held down for. It also had special collision responses based on what stage the flippers were in, which proved a challenge when sprites could easily go through them.

What made working on this engine quite exciting was it really encouraged you to work with proper limitations. Unlike pico-8, where the limitations are hard-coded into the engine and its fantasy console, the command prompt had a small resolution and a limited colour palette purely because it was not intended for real-time rendering and gameplay, and the 1.44MB meant I had to think outside the box to find ways not to use too much memory, although, in the end, PEWBALL was under 400KB (possibly smaller still if I could get a compress heavy linker like crinkler to work).

One way to optimise was to replace having a particle emitter with particle objects with the rand() function and lots of basic maths to work out where particles would be over time. This technique was used for the starfield at the beginning as well as the explosions enemies and the player has in the game. Guns used a simple fixed sized array as an object pooling system, a similar one was also used for the enemies, which had their own struct that could be overridden for unique behaviour. Ogg files were compressed to their lowest quality, which gives them a small file size as well as gives a slightly distorted retro feel, helped by the 8-bit inspired music and sound effects that I used.

While I could have carried on development up to the deadline on August 10th, I needed to get a game finished for July, so I decided to stop on July 31st and submit it, announcing it’s release on August 1st. Little did I know, there was also a voting session that went on for a while. Out of the 25 submissions managed to achieve 7th, and the overall winners were Floppy Bug (In Quality and Design) and Crates in a Crate (in Gameplay). I’m pretty happy with where I placed considering the challenge I had in creating an entire engine, although I’m definitely impressed with Floppy Bug because the team behind it decided to one-up me and create a full 3D OpenGL engine in two weeks that took up 440KB.

Regardless, this one was a rather fun challenge. It kind of makes me want to look into development for other primitive systems, maybe I could try developing for an old console next, who knows? As for Linux, that might not be as possible as I hoped it would be. The problem with Linux Terminals is that they don’t have the same level of control as the Windows Command Prompt. It is possible to do things like resizing the terminal window, draw characters at certain positions and set the colours of characters using ANSI escape sequence strings, however, it isn’t as stable as I once thought, and there isn’t much documentation on getting it to work.

If you want to check out the engine itself, it’s called KitConsole and can be found on Github, and you can check out PEWBALL on Itch.io.

SFML 2.5.0 Update (Or how I learned to hate RenderTextures)

 

 

On May 6th, the C++ Simple and Fast Media Library (or SFML for short) was updated to stable version 2.5.0, adding various updates including more optimial iOS support, bug fixes, added functionality for Text and Audio and various optimizations. For such a big release, it made sense to upgrade and get my Vigilante Game Framework updated, and why not update Gemstone Keeper while I’m at it?

Well it took nearly a month, but I did manage it in the end. Gemstone Keeper 1.0.5 has been uploaded to Steam, both for Windows and Linux!

As the title suggest, a lot of the work had to do with the updates to the sf::RenderTexture object. However, I don’t absolutely hate them, they are extremely useful for rendering a scene to an area of the screen, or to apply post-processing effects to. However the problem lied in how I was using them, and how the fixes done in the latest update effectively broke my engine’s rendering system.

The initial update showed promise, as my most recent game worked fine, but moving onto the framework’s examples and Gemstone Keeper showed that a lot of things weren’t rendering at all.

Vigilante Framework currently renders 3D models using Modern OpenGL, and while it was working fine with SFML 2.4.2, it rendered nothing with SFML 2.5.0. The solution was embarrassingly simple despite the amount of effort put into fixing it, including implementing my own version of SFML’s glCheck function and re-writing SFML’s own OpenGL example to run with modern OpenGL. When rendering the 3D scene, I modified some of the OpenGL states, which wouldn’t be an issue before but now those OpenGL states carry over into other contexts. The solution was to simply make sure that the GL states were reset BEFORE rendering the scene using a sprite object.

 ///Render 3D scene and apply to a sprite.
 RenderTarget.resetGLStates(); //Reset the GL states to the default for SFML
 Sprite->Draw(RenderTarget); //Render the sprite.

Gemstone Keeper however uses legacy OpenGL, and while I could have updated the VFrame source code but that could take more time to fix. Regardless, I was able to get it working by rearranging other objects that define sf::RenderTexture, including the bloom post processing effect and the help popup terminal.

Gemstone Keeper’s other graphics were another story. The approached I had been using up to this point was to render text objects onto a single rendertexture, and then store the generated texture to be used as a sprite, particle or tilemap. While this was okay for the time, but it is rather inefficient and bad for graphical memory.

I wanted to do a single-texture approach, where all the graphics are rendered onto a single texture, and a rectangle area is specified when creating renderable objects, for a while but I kept putting it off. SFML’s update, causing any newly created render textures to dereference generated textures, it was time to take this approach on. The best part is that most of the work was already done by myself with the additional code of Jukka Jylänki’s MaxRectBinPacker algorithm, all that needed doing was to change how I defined renderables from setting the texture to whatever the name of the genrated texture is to the name of one texture sheet, and to get the correct rectangle from a map/dictionary, searching by string ID.

CaptureCaptureCapture

Now this doesn’t mean the entire game’s visuals are rendered from one texture. Including the 3D gemstones, any assets that use a repeated texture grabs a subsection of the main texture as a copy, same applies to the VBackdrop as well. Getting the icon was a more painful looking process of converting the entire texture sheet to an sf::Image, so I can load in a subsection to a new sf::Texture object, and then convert the new texture object to an sf::Image in order to set it to be the application icon.

sf::IntRect iconArea = TextureData::p()->GetTextureRect(TextureData::p()->GetPortalTextureName(true));
 sf::Image image = VGlobal::p()->Content->LoadTexture("TextureSheet").copyToImage();
 sf::Texture tex;
 tex.loadFromImage(image, iconArea);
 VGlobal::p()->App->setIcon(iconArea.width, iconArea.height, tex.copyToImage().getPixelsPtr());

Like I said, not pretty.

So enjoy Gemstone Keeper, the number of you who own it. Now back to doing more stuff in C++…

Roguelikes and a Faulty Computer

I hope things are going well with all those who read this, whether it be while hard at work or relaxing while browsing their social media. Since GDC 2018 happened, it took a while to adjust me back to a work routine. It didn’t help that the week after I returned to the UK I was off to Bristol celebrating a four-day weekend with friends and family for my birthday. Fortunately, with my day job going on, I have managed to recover from jetlag and get back into a coding routine with some bumpy roads. I figured it’d be good to detail what went on up to now.

RDDL

The Games Jam for March was the Seven Day Roguelike (or 7DRL for short). This is a long-running one-week games jam dedicated to the roguelike genre. This year was the first year they hosted the jam on itch.io, instead of the Roguetemple forums and other hosting services that had since gone defunct.

The first time I took part in 7DRL was in 2016 with Dungeon Racer, while I was glad to get a game done using my engine for the first time since Gemstone Keeper’s early demos, in hindsight the concept was a bit too out of reach for me without preparation. This time I decided to do a bit more of a simple roguelike.

RDDL (pronounced Riddle) was originally going to be a dungeon based roguelike in the style of the Crystal Maze, where the player would have to find a key in each room to progress. Health would decrease over time and the only way to regain health was to either find it through treasure or defeat enemies. I used the GenLevelTools like I did previously, however, I noticed how lacking some of the features are (particularly with tilemap generation).

I ended up using the tile mapping system for this, which worked well with the tilesets made for Dwarf Fortress. I had considered adding the ability to change tilesets like I did previously with Dungeon Racer but I ran out of time. I also got to take advantage of GL-Transitions again with a cool grid flipping transition, people on the roguelikes Discord liked it so I took full advantage of it.

Overall it’s great to get a proper working roguelike, especially one that people would undisputely call a roguelike unlike my previous games. As of writing, voting has just ended on all entries, so you can check out how well it did on itch.io. Feel free to check out all the other entries too!

Speaking of previous games…

Gemstone Keeper: One Year On

As March 31st of this year is the one-year anniversary of the release of Gemstone Keeper on Steam, I figured it was a good idea on Twitter to talk about how it’s done and what I should learn from it. You can check out the start of the thread below.

I was inspired by Eniko of Kitsune Games to do this, after a tweet she posted on how stressful being an indie developer was. I feel it’s necessary to let people know that despite the success stories, a lot of stories aren’t as impressive. I still maintain that Gemstone Keeper’s response was positive, considering the circumstances, and I still appreciate the support and feedback people give.

Technical Issues

So on Thursday 5th April, I was reading an article on my main game development and home desktop machine when suddenly I got a Blue Screen of Death. I initially thought this was typical, at least until the machine restarted and would go to a blank screen. I tried restarting again and the same blank screen appeared. I checked the bios and the hard drive looked fine, but the same blank screen.

Then after taking out all other drives, I tried again and this time it says that there are no bootable drives found… this doesn’t sound good. After a few diagnostics and checking the hardware with the help of some friends, we’ve come to the conclusion that while the hard drive is fine, something happened when the BSOD hit that caused the Windows OS to come corrupted.

The good news is that nothing has been lost. All of my game development work as well as personal files and other, less relevent, projects have all been backed up on either external HDs or online cloud services (meaning that after my last major technical mishap over three years ago, I’ve definitely learned from my mistakes). Not to mention that while I cannot boot into Windows, I am still able to access the HDD using a bootable Linux drive, so anything on it is still salvageable.

As a result of this incident, it’s been decided that it’ll be better to upgrade components of the desktop instead of trying to repair it. The current HDD is a little over six years old, so even if I managed to fix Windows then who knows when the drive completely dies. Plus with more modern components, I can take advantages of any addition performance of say, an SSD for the OS and a HDD for data as opposed to a HDD for everything else.

Hope that clears up everything. Just like to make two short announcements, I’ve began on a new project, development will continue once the upgrades have been finished sometime this week. The next games jam I’ll take part in for April will be Ludum Dare 41.

Enjoy April folks!

New Years Resolutions

Good evening everyone! It’s no doubt that 2017 has been a hell of a year following what happened in 2016, but we fought through and we are still here fighting! This year has also been huge in terms of game development for me. I managed to finish SEVEN games this year, six from game jams such as #RemakeJam, PROCJam, Jamchester and Three Ludum Dares!

https://img.itch.zone/aW1hZ2UvMTYzMjc3Lzc1MjE2Ni5naWY=/315x250%23c/L0i8g2.gif  https://img.itch.zone/aW1hZ2UvMjAxMDM1LzkzOTE3OC5naWY=/315x250%23c/q5QpUK.gif

The seventh game was the nearly two year project Gemstone Keeper, which made an initial release on March 31st earlier this year and has since had numerous updates, although grouped together as four updates. The most recent of which was 1.0.4 that was announced on 21st of December. The game is currently on part of the Steam Winter Sale, and is currently 50% off!

Gemstone Keeper also had a second smaller release as it was ported to Linux, the build being available on Steam in June. I documented the progress to port the game in three blog posts (part 1, part 2 and part 3), and got a small amount of coverage from dedicated linux gaming websites as a result.

There was also an accomplishment in travel as well, 2017 was the year I went to both GDC in San Francisco and Develop in Brighton for the first time! Both events were great opportunities to meet up and socialise with fellow game developers and listen to talks from great minds such as Ken Perlin, John and Brenda Romero, Jordan Mechnar and Tim Sweeny.

As for 2018, I want to set some goals. As with many New Years Resolutions, chances are they will be forgotten and unaccomplished, but considering I managed to lose weight this year, I might pull through with a bit of committment.

First one is that I want to take part in at least one game jam a month, meaning I’d be finishing 12 games next year. I like the challenge and creativity from game jams, but this year I feel like six isn’t enough. At least spacing out the game jams to one a month will give me time to find a weekend or so to get my head down and finish something.

Second one is to get a game on console. It’s not like I haven’t bothered trying before (I’ve reached out to Nintendo about developing Gemstone Keeper for the Switch to no avail), but it would be nice to expand my work beyond desktop PCs and web development. Porting my own game to Linux should show how when I put my mind to it, building a game to another platform by hand is possible, and it would be great to show I can do that on one of the three main systems.

Thanks for reading and have a happy new year everyone!

The More You Have, the Worse It Gets

Ludum Dare 40 took place last weekend, the theme was the title above. Honestly it wasn’t the theme I was hoping for, but in the end, I took an idea I had and adjusted it slightly to work.

The idea I had was that a single level would slowly get corrupted and change, you can shoot away the corruption, but touching the corruption would kill you. This already could fit the theme quite well, the more corruption in the world means the worse it is for you. I wanted players to move around a lot, so I had the additional goal of collecting glitch boxes, which would create more corruption over time.

I used HaxeFlixel to develop the game, as it was bread-and-butter for me in game jams such as Ludum Dare, especially when there is not much time to work on an idea (I had spent the entire Saturday out with friends for winter festivities, all I did was write notes on what the idea would be, so in all I only had around 11 hours to work on a game).

b056


To get the corruption to update and move around, I used the tilemap system and updated the grid with Conway’s Game of Life algorithm, that way it gave the impression of mutating outwards or dying out depending on the numbers. Fortunately, with recent updates to HaxeFlixel, you could do collision response based on specific tiles, so it was easily possible to remove tiles and change the map when bullets collided with it. The extra artefacts also use Conway’s Game of Life. although the grid is 4 times larger than the main corruption grid.

The artwork was done in Photoshop, although it was a very simple and rushed job. The “corrupt” graphics was a multicoloured character set that I had to create and tweak by hand to fit into a 10×10 pixel grid.

The music was a combination of cgMusic and LMMS, quite a good combo to have because it meant I let one program generate a music set, then import it into LMMS as a midi file for me to set instruments (using soundfonts), effects and tweak the melodies how I like.

I managed to upload the game with around 30 minutes left before the compo deadline!

b05c

On Tuesday I fixed that timer, which appeared broken when you reached a minute because I messed up how the string was being built. It took a few uploads for those changes to appear, something that kind of frustrates me about HTML5 and how web browsers will not always clear out the cache if the content has been changed.

GIF

Feel free to play the game on itch.io as well as rate or comment on the Ludum Dare page.


This wasn’t the only games jam I did this winter, I also took part in PROCJAM, where I built a planet generator. It’s not my best work to be honest, although I was able to work and improve my 3D OpenGL rendering in the Vigilante Framework.

Managing Content and the Joys of Smart Pointers

Hello everyone, I figured I’d write a post about something I’ve been working on for the last week or so, partly as a bit of advice for some budding programmer wanting to write a bit more low level games programming stuff, but also to try and explain why it has been several weeks since I last posted about a small prototype I’ve been working on, and why I have been posting less stuff on Twitter than usual.

To put it basically, a lot of C++ work, mostly involving Gemstone Keeper. I decided to go back to it one more time after a lot of bugs and feedback came in. By the time I’ve posted this, Gemstone Keeper has been updated to version 1.0.3, which includes bug fixes, UI updates and two new enemy types.

j7fcaz6

 

While most of this wasn’t planned (most of this would have happened much earlier if I was notified on Steam within days of it being reported), but it had been on mind for a particular reason.

To put it simply, I have been updating my C++ game framework, the Vigilante Game Framework. This is the framework that I had built up alongside the game it was made for, Gemstone Keeper, before open-sourcing it in the hopes that it could be improved for more projects. I noticed a problem with the content management system, and as such I had spent the last two weeks researching and implementing a new way that would make it more optimal while keeping it stable. Because of this, Gemstone Keeper will soon be updated with this improvement among other bug fixes, and any future games using the VFramework will feature this too.

dytc50n


Here is the original code for loading and setting an sf::Texture in my content system, according to the repository for Gemstone Keeper this was initally written around Feburary 2016, and aside from one change in April this remained how it was:

bool VContent::LoadTexture(const sf::String& name, sf::Texture &texture)
{
   if (FindTexture(name))
   {
      texture = textureDir[name];
      return true;
   }
   else
   {
      if (texture.loadFromFile(name))
      {
         VLog("%s loaded", name.toAnsiString().c_str());
         textureDir.insert(textureDir.begin(), std::pair<sf::String, sf::Texture>(name, texture));
         return true;
      }
   }

   VLog("Error loading texture: %s", name.toAnsiString().c_str());
   return false;
}

The approach should be fairly straightforward:

  • If a texture exists, set it to the texture object and return true.
  • If it doesn’t exist, load it using the texture object. Return true if load is successful.
  • If it cannot load, return false.

However there is one problem, setting the texture object doesn’t set the reference, despite passing the object in as a reference (hence the &). Instead it creates a copy, with a new texture ID and references.

Performance wise, this doesn’t have much of an issue, however memory wise there could be a concern with creating several sprites with the intention of using the same texture, but it isn’t. The intent of a content manager is to load, unload and store a single instance of an asset, with any objects merely referencing that content. I investigated a number of approaches (and spoke with eXpl0it3r of the SFML team) to find the right one.

The approach I finally went with required the following changes:

  • The load function should return the object itself as a non-pointer reference, not a bool. This is to ensure that if the loading or finding process goes wrong, the program should let you know and fail. The reason for a non-pointer is to ensure you wouldn’t return a NULL object. Returning a reference makes sure not to return a newly created copy.
  • If it cannot be loaded, an exception should be thrown. Exception handling is an ideal alternative to responding to function returning false, because it’ll make a function closing on failure much easier.
  • The texture should be stored as a unique pointer.

The reason for a unique pointer, instead of a regular or “raw” pointer, is to ensure that the object only has one true owner, and that once it’s dereferenced (either by closing the game or unloading it) it’ll be properly destroyed and unable to be used by other objects, all with little to no difference in performance. While a unique pointer cannot have more than one reference, the raw pointer can still be obtained and used, just make sure that once the content is unloaded there aren’t any active objects still referencing it.

This is what the texture loading function looks like now (from the Github Repository):

sf::Texture& VContent::LoadTexture(const sf::String& name)
{
   auto found = textureDir.find(name);
   if (found == textureDir.end())
   {
      std::unique_ptr<sf::Texture> texture = std::unique_ptr<sf::Texture>(new sf::Texture());
      if (texture->loadFromFile(name))
      {
         VBase::VLog("%s loaded", name.toAnsiString().c_str());
         textureDir[name] = std::move(texture);
      }
      else
      {
 #ifndef __linux__
         throw std::exception(("Error loading texture: " + name.toAnsiString()).c_str());
 #else
         throw ("Error loading texture: " + name.toAnsiString());
 #endif
      }
   }

   return *textureDir[name];
}

To use the functions in this format, I had to change a lot of objects around the game. Textures, Images, Fonts and SoundBuffers all changed to use raw pointers, and the returned values from the functions are converted to functions as well.

texture = &VGlobal::p()->Content->LoadTexture(filename);
sprite.setTexture(*texture);

This ensured that the object being set is has the same reference as the object being returned, no more copying data, no more instantiating new objects to handle the copy.

I’ve also turned a lot of other objects into unique pointers, particularly the objects in VGlobal, which is intended to only have one instance of. It’s ideal since these ones are all destroyed at the end, and in a scenario where an object could be replaced with another one, the unique pointer can destroy the old one in order to replace the new one.

Other small changes I’ve made to update the framework includes all objects that load textures now having an optional area rectangle. This was mainly put in if multiple sprites use the same texture, but different atlases. Best example would be in the LoadGraphic and setSize functions of VSprite, where the default parameter will ensure the whole texture is used, else the animation system will restrict the render area of the sprite to that rectangle. While sf::Texture does have the ability to load a rectangle area of a texture to an object, I feel like this only adds a separate texture, instead of the one loaded and taken from VContent. At some point I’d like to use this more for Gemstone Keeper and other games, as I see reducing the texture count and having more render calls using the same texture would have additional benefits, no matter how small.

Hopefully more changes like these will benefit games I make with this framework, I’d also like to use more smart pointers, maybe shared pointers for my general objects, but for the time being, I’ve got a project to get back to.