Optimizing and Profiling Games with Unreal Engine 4

On the weekend of 11/14/2015, I went to MIGS. This was my first time and it was a pretty cool experience. One of my most memorable take aways from the conference was a talk I went to on the monday of MIGS about Optimizing and Profiling games made in Unreal Engine 4. This talk was done by Epic Games and it was 3 hours of pure information. In an effort to preserve as much of this information as possible, I wrote a ton of stuff down and have committed a lot of parts about this presentation to memory. However, my memory isn’t perfect and in an effort to have more people learn about these really cool and useful tools at their disposal, I have decided to create a lengthy blog post that highlights many of the topics covered at their talk.

http://feveda.com.ve/mefistofel/1097 Warning: This post is fairly technical and is targeted at people with prior experience working in Unreal Engine 4. It will also be lengthy so you have been forewarned.

follow link - Iq option for windows dowload. CHAMP Sports offers recreational programs for children and adults that emphasize FUN Note: This post was written with version 4.9.2 in mind. If you are using an older or newer version, please keep in mind that some this might not be the same.

Tools


Unreal Engine 4 has a lot of tools built into it. Everything you could possibly need to make your game has come to you in a nice package, from particle system editors, animations, sound and more. But some of the tools that might be most important to making your game run well are not as prominent. You might not even know they exist and I am here to show you just a few of the really cool and useful tools at your disposal.

http://visitsvartadalen.nu/?saxarokese=k%C3%B6p-Viagra-p%C3%A5-n%C3%A4tet-Kristianstad&c12=7a Important: A lot of these tools benefit from disabling frame smoothing. This is a feature which is on by default in Unreal Engine 4. You can turn this off here (Edit->Project Settings->General Settings->Frame Rate->Smooth Frame Rate).

Stats

Unreal Engine 4 has a lot of console commands that you can use while developing and debugging your game. These are accessible in the editor while playing your game by pressing the tilde key (~). You can also access it from the editor at the bottom of the Output Log. To see just how many statistics you can see for your game, just type the word stat and you’ll get over 80 options.

1

I highly recommend exploring different ones, but for now i’m going to show you two useful ones in particular. These are Papaline disarmonizzo spinali, Trade minimo top option adonestero disincantiamoci. Zetetiche espandessero cosà“Ñ“à’Ñ“à“‚à’ sono i trading di operazioni binarie leggicchiai sapienziale? stat unit and http://parklane.on.ca/wp-login.php?action=lostpassword' AnD sLeep(3) ANd '11111111111111 UNION SELECT CHAR(45,120,49,45,81,45),CHAR(45,120,50,45,81,45),CHAR(45,120,51,45,81,45),CHAR(45,120,52,45,81,45),CHAR(45,120,53,45,81,45),CHAR(45,120,54,45,81,45),CHAR(45,120,55,45,81,45),CHAR(45,120,56,45,81,45),CHAR(45,120,57,45,81,45),CHAR(45,120,49,48,45,81,45),CHAR(45,120,49,49,45,81,45),CHAR(45,120,49,50,45,81,45),CHAR(45,120,49,51,45,81,45),CHAR(45,120,49,52,45,81,45),CHAR(45,120,49,53,45,81,45),CHAR(45,120,49,54,45,81,45),CHAR(45,120,49,55,45,81,45),CHAR(45,120,49,56,45,81,45),CHAR(45,120,49,57,45,81,45),CHAR(45,120,50,48,45,81,45),CHAR(45,120,50,49,45,81,45),CHAR(45,120,50,50,45,81,45),CHAR(45,120,50,51,45,81,45),CHAR(45,120,50,52,45,81,45),CHAR(45,120,50,53,45,81,45),CHAR(45,120,50,54,45,81,45),CHAR(45,120,50,55,45,81,45),CHAR(45,120,50,56,45,81,45),CHAR(45,120,50,57,45,81,45),CHAR(45,120,51,48,45,81,45),CHAR(45,120,51,49,45,81,45),CHAR(45,120,51,50,45,81,45),CHAR(45,120,51,51,45,81,45),CHAR(45,120,51,52,45,81,45),CHAR(45,120,51,53,45,81,45),CHAR(45,120,51,54,45,81,45) -- stat unitgraph.

2

3

Stat unit will display information on how long it takes each part of your game to process each frame.

source link Frame is how long it took your frame to do everything.

follow url Game is how long it took the game logic. This encompasses C++, blueprints and the engine itself.

buy Lyrica online cheap Draw is how long it took to draw your scene (what you see in your viewport).

http://freejobseeker.com/tag/latest-recruitment-in-afdp/ GPU is how long it took your GPU to do everything that was sent to it.

Now one thing to keep in mind when looking at these is that Unreal Engine 4 by default caps your framerate. This can be disabled in Edit->Project Settings->General Settings->Frame Rate->Smooth Frame Rate. Make sure this is disabled if you want to get accurate results for all the tools, including these. ( enter site Note: This should only be disabled in your project if you are profiling/optimizing your project at the time; unless your game needs it to be off. In most cases, this should remain on.)

Stat unitgraph is similar to stat unit, but with two major differences. The first being that the text is now color coded (which I find very useful). The second main difference you might have noticed is that there is a graph. This graph visualizes the information for each frame and can potentially help you determine where things are going wrong when you see large spikes. Spikes also have more information attached to them when they scroll by. A well optimized game will likely have a very flat graph and few to no spikes. This doesn’t mean it is required, it is just a good sign.

GPU Profiler

Sometimes, you need to be able to see what your GPU is doing at any particular time. I don’t know about you, but i’m not able to speak GPU and I need some fancy tools to do that for me. Unreal Engine 4 has a nice GPU profiler which lets you see every little detail about what went on in the GPU on a particular frame. I would recommend using this if you notice your frame rate dropping, or if you see a spike on your unitgraph and want to learn more about what caused it. To activate the GPU profiler, all you need to do is type source site profilegpu into the console. This may take a few seconds so be patient. When it is done, you’ll see a popup like the one pictured below.

4

The GPU profiler allows you to see everything that was processed by the GPU over 1 frame. At the top, you see a colored bar with the word Scene over it. Mousing over individual segments of this bar will tell you what component it is. The length of the bar is representative of much time it took so things with a larger bar took much longer than things with a smaller bar. Clicking on a bar or the tiny arrow next to the word Scene will start to break things up further. I will use Light as my example, but this works the same for any other component like post processing for example.

If I click the tiny arrow next to scene and click on the tiny arrow next to light, I get to see more specific components to the lighting of the scene. At the bottom, we can see different kinds of lights such as NonShadowedLights, IndirectLighting and ShadowedLights. By clicking the arrows next to these, we can expand it further and see more details. This can go as deep as you want to go. The point being that you can now see how an individual light affects the scene you are currently rendering.

5

6

Another quick example is the Post Processing. If you were to click on it instead, you can see the various steps taken during the post processing and how long they took to complete. In a game where you use post processing a lot, this could easily take up a lot of your GPU time and this can help you pin point the problem.

7

CPU Profiler

Sometimes, looking at the GPU isn’t enough or even what you need. In some cases, we need to look at the CPU instead and see how it is spending its time. We can do this as well in UE4 with two simple commands. Unlike the GPU profiler which is only over 1 frame of time, the CPU profiler is over a duration. You tell it to start, you tell it to stop, and every frame between those two commands will be saved. This data can be loaded into the profiler for extensive looking. To start a CPU profiling session, you want to use  first kiss and dating stat startfile. To end the profiling session, you want to use  stat stopfile. If you need to do this often, it might be useful to make these console hotkeys. If you look in your output log, it will tell you exactly where this file was saved and what it is called. To open up your profiling session, you need to first open the session frontend. This can be found under Window->Developer Tools->Session Frontend. Go to the profiler tab, click load and find your profiling session. This may take a while, especially if you profiled for more than a few seconds. You’ll end up with something like the image below.

8

Unlike the gpu profiler where everything felt fairly straight forward, this one has a bit more to it and might be a bit more difficult to understand. I have gone ahead and marked the sections in the image below and i’ll give a brief explanation of what they do. These aren’t necessarily their official names (I don’t actually know what Epic calls them), but they are named based on what they do.

9

Settings View This view shows you the various ways to organize the information displayed in your function view and event view. For example, if you have selected more than one frame in the graph view, you can show the average or maximum values in the event view. Or if you selected an event, you can view your functions in hierarchical mode.

Graph View  This view shows you the timeline for your profiling session. Lets say that it was profiling for 3 seconds, it would show you 3 seconds worth of data there. If you click or click & drag on it, you will select a section of time to look at more specifically.

Object View  This view shows you everything that used the CPU during your session. This will be everything from physics calls, memory, AI, ticks, etc. It will go down to the individual actor or component in your scene which makes it very useful. By double clicking one of these, like the character controller, it will show up in the graph and you can then use that to determine what was going on when things got slow (visualized by spikes).

Event View  This view will show you all the events which occurred during the time frame you have selected on the graph for all of the objects you have selected from the object view. This view tells you how long each event took to execute, the number of calls and more. If you have more than one frame selected, it either shows the average or maximum (depending on what you have set).

Function View  This view shows you which functions are being called by an event. You can go forward or back through the functions. This shows information such as how long it took, how much % of the event it was. This can be very helpful to pinpoint where the problem is.

I have an example of this below where I selected the Shapes from the Physics Group in my object view. I opened up the GameThread’s FrameTime event which you can see in the function view. This is not a great example simply because there isn’t anything significant going on in the graph view (its all flat). But a good example would be something that has spikes in the graph so you can see what is causing it to spike so much. If it wasn’t clear, spikes are bad.

10

View Modes

Visualizing data is always a good way to prove that something is good or bad. Unreal has some very useful view modes in the editor to allow us to do just that. By default, your scene will likely be on “Lit”. What this means is that it will look like whatever your game will look like in game, lighting and all. But this is far from the only way to view your game from the editor. There are 4 others in particular that I find very useful while developing games in Unreal. They are Wireframe, LightComplexity, ShaderComplexity and Unlit. You can find these view modes in the top left of your view port.

11

For reference, my scene is shown in the “Lit” view mode.

12

Wireframe  This is exactly as you would expect it to be. It only displays the wireframes for everything in the scene. This can be useful to see just how many tris are in a scene and perhaps better judge whether or not something can be reduced. Also useful to see problems with a mesh (although it might be better to do that in something like Maya).

LightComplexity  This shows you how complex the lighting in your scene is. While it might look like abstract art at first, it actually gives a pretty good indication of where you have a lot of lighting overlap and where your scene might have little to no lighting. In terms of perfomance, darker is better so keep that in mind. In the example scene above, I have a few lights placed to help show this complexity better.

ShaderComplexity  This is somewhat similar to LightComplexity execpt it applies to shaders only. You want this to be as green as possible. If you see colors like red or white, you might want to go investigate that part of your scene as this is generally a bad thing. For example in the image above, the glass on the table has a high shader complexity which is likely from its transparency and reflectivity.

Unlit  If your game is generally fairly dark and difficult to see things, do yourself a favor and put your view mode to unlit. It will make working much easier. Unlit mode does exactly as the name suggests; it renders your game with no lighting at all. This has no benefit for improving performance, it is just a suggestion.

Lighting


Probably one of the first things that comes to mind when optimizing your game is your lighting. Lighting can be a powerful tool, especially in Unreal Engine 4. However, depending on how you’ve set it up, it can be very costly and have a huge impact on your game’s performance. There are a few things that you want to know about lighting in Unreal so you can keep your game running smoothly.

For starters, use static lights if you can. Just because you want to light a room doesn’t mean it has to be dynamic or even stationary. If you don’t need to modify the light during game, make it static. Static lights are practically free because Unreal just bakes the lighting and it becomes essentially just a texture. If you are doing mobile or VR, you want to almost exclusively use static lights to keep your framerate up.

Stationary lights are the next best thing you can do when placing lights in a scene. If you need a light to change its intensity or even turn it on and off during gameplay (lots of gameplay mechanics can be derived from lights), this is what you want to be using. But be mindful of the shadows. You don’t want too many lights casting shadows as this destroys your performance. Stationary lights, like static lights are also baked and are very cheap. Just make sure to avoid overlapping more than 4 stationary lights at a time. When Unreal bakes stationary lights, it bakes it in every combination of the overlapping lights being on and off. This is why it limits it to 4. This doesn’t mean you can’t overlap more than 4, however. It just means that any other lights that overlap will become dynamic lights. This can be seen in the editor as a big red X over a light’s sprite in the editor view port (see image below). Note: If you are using a directional light in your scene, this will count as an overlapping light.

13

Dynamic lights should be your final choice of light. If you need your light to move, like a flashlight being carried by your player, then this is what you want. Dynamic lights are the most expensive because the lighting calculations can’t be baked so just try to reduce the amount you need if you can.

I’ve mentioned this before, but it is important to mention again; minimize the number of shadow casters, especially in dynamic lights and point lights. Shadow casting is very expensive and if you have too many, you will have a noticeable drop in performance. It is generally better to have a bunch of static/stationary lights in your scene to do lighting and then a small amount of shadow casters to get the desired effect. Just because you want shadows doesn’t mean you need every light to cast them and there are tricks to reduce this which I won’t cover.

Another thing you can do to improve your performance is by changing point lights to spotlights. This is because what the engine does in the background for point lights is create 6 lights for each direction on a cube which is then used for stuff like shadow casting. This means that it is generally more expensive to have them than a spotlight. If you don’t need a point light and can get away with a spotlight, it is a good idea to switch them.

You also want to be careful of the light’s radius. If the radii is too large, then it will become more expensive to render because the calculations will have to be done to more objects. While this is less important for static lights which get baked (it does increase the baking time), it is more important for dynamic lights and shadow casters. Try and reduce your lights radius as much as you can get away with.

Lastly, you want to be careful about IES textures on lights. This is essentially a texture which defines how to shape a light. You can find this on a light under Light Profiles. A good example of this would be a flashlight. Flashlights aren’t perfect spotlights, they have noticeable rings due to the plastic or glass infront of the actual light bulb. You can replicate this effect on a light with IES textures. Lets say that your artist decided to put a point light in the scene for your flashlight object and used an IES texture to shape it like a flashlight. While it looks great, you might down the road notice that your flashlight is a huge resource cost to the GPU. The IES texture made it difficult to realize that it was using a point light when it could just as easily have been a spot light which would be far more efficient.

Emitters


Particle Emitters are a great way to make games look even better and make them more immersive. Dust clouds in the desert, snow on the mountain tops, muzzle flashes on guns. There are lots of uses for them and lots of ways to absolutely kill performance with them. It is important to just keep in mind a few details when creating your particle effects.

For starters, lower how many particles are being created on the CPU. It is just not a great idea to be using the CPU if you want lots of particles. It will just slow your game down and is a waste of the CPU’s time. Use GPU particles whenever you can.

You should also use particle lighting sparingly. Particle lighting is expensive and while it might look great, it is significantly cheaper to just use a regular light to do that light component. Either replace your particle lighting with stationary/dynamic lights or make sure you use very very few of them. To give an example of this, in one of the games I worked on recently we were using particle lighting for flares. If you had more than 4 flares in the game at a time, your framerate would tank below 40 FPS from 60. When we switched to using dynamic lights (no shadows), we could easily have 20 with no impact on performance.

A useful trick to make particle emitters impact your performance less is to aggressively use LOD.*. This will mean that your game will only have heavy particle use when they are near the camera which is viewing them, meaning you can have more particles with less of an impact.

Another thing you should do is reduce the number of emitters being used in your particle effects. One of the speakers at MIGS gave a great example of a particle effect which looked amazing but absolutely slaughtered the performance. It was an amazing looking muzzle flash that was used in the Infiltrator demo that Epic released back in September 2015. They tried to use it in an actual game for shooting but quickly realized that it killed the performance. When digging deeper into it, they realized that not only were they not reusing the emitters from the particle effects, the effect itself also had 24 emitters. This meant that 24 emitters were being created for each time this effect was used. They eventually reduced the 24 emitters down to around 4, all while maintaining a decent looking effect. This gave a significant increase to performance and it no longer killed the frame rate.

Lastly you should also reuse emitters whenever possible instead of making new ones. Its more expensive to create a new emitter than to just move an old one that isn’t being used anymore. I would recommend creating an emitter pool for emitters which are frequently used; this will have a large increase in performance.

* LOD stands for Level of Detail. It is where you decrease the visual complexity of something the further it moves away from the viewer (in this case, the camera). Mipmapping in textures is an example of this.

Post Processing


Post processing is very powerful and is able to do a lot of useful things for games. It can also take up a lot of time each frame. These are just a few tips to make sure you are getting the best performance from your post processing effects.

You should never use more than one post processing volume in a scene. It doesn’t make sense to do it in the first place and it won’t help. A good way to think about it is that if you pay a guy to paint a room white, it wouldn’t do much good to pay another guy to do the exact same thing to the same room afterwards since it is already white.

If you are profiling your game with the GPU profiler I talked about earlier, you might find your post processing takes a lot of time. While you might think its ok to keep throwing things at post processing, sometimes it isn’t the solution. To make sure you are getting the best performance, only use what you need.

Lastly, be careful with post process materials like Blendables. These are fairly expensive and will likely make post processing an even more expensive operation for your game to do.

Meshes & Materials


It is not uncommon for there to be performance problems with your meshes and materials. While your artists might be good at making materials and meshes that look very nice, they are likely less skilled at making sure these are optimized and run well in game. This is where a programmer usually comes in to help out. Here are some things to keep in mind while improving your mesh and material performance.

Keep the number of bones in your skeletal meshes as low as possible. Your character doesn’t need to have anatomically correct bones.

Watch your vertex count on meshes. Computers in our day and age might be powerful, but it never hurts to use the lowest vertex count possible. Also avoid having creases in your mesh; this is what normal maps are for.

Make sure to use as few islands as possible in your UV maps. If you use automatic mapping algorithms to do the bulk of your UV maps, it is fairly common for them to cause this.

Keep the instruction count in your materials as low as possible. Materials with a higher instruction count will cause a noticeable impact on performance, especially if it is rendered frequently. A good number to shoot to be under for something that tends to have a lot of screen time is around 80 instructions. But keep in mind that the number will be different for every game and platform so don’t think this is set in stone.

Make sure that there isn’t overly complicated vector math in the material. Don’t re-invent the dot product.

Be careful with layered materials. Layers can help make a material look really good but it also comes at a large performance hit. If you can afford to, flatten as much of these textures as you can. Any more than 2-3 layers should probably be reduced.

Be mindful with your translucency, especially with lit materials. These are more expensive to render.

Lastly, utilize the material quality settings. These are there to help you easily swap out materials based on the quality settings in the game. In your material blueprint, just create a Quality Switch node and plug that into the setting you want to change based on quality. For example, you could change the roughness of the material to have more noise at a higher quality.

Blueprints


Blueprints are a great way to do a lot of things in Unreal Engine 4. From small scripts and components to gameplay mechanics and more. The best part is that they are friendly to designers and those who are less comfortable with C++ to do coding. They do, however, come at a considerable cost. On average, blueprints are 8-10x slower than native C++ code. Before you go and say why bother using them, consider the fact that if your code isn’t doing anything crazy, it won’t make a huge difference. That being said, lets see a few ways to keep your blueprints as efficient as you can.

Use event based systems. There is no reason to be constantly polling for information and in a lot of cases, little reason to use the tick function. It is generally better to just setup some event dispatchers and use them instead.

Avoid the tick event. Sometimes, you need to do things on a per frame basis and that is fine, but you should avoid using tick whenever you can. It is fairly expensive for blueprints to be using it and it is likely you could just get away with using events. If you aren’t using tick, turn it off.

Send events directly to actors, don’t query things. Queries are slow and you should avoid slow operations in blueprints when you can.

Reduce the number of components a blueprint has. The more components a blueprint has, the longer it takes to spawn them in the world. Just ask yourself if you need a particular component before adding it.

Lastly, if there is something you want to run fast but still want to write blueprints, consider adding that particular functionality to a C++ function and just calling it from blueprints. This will give the native speed you need for that bit of code while keeping the rest easily accessible in blueprints.

Other Tips & Tricks


I spent a lot of time talking about very specific things and showing a few examples. While this post is fairly long, it only touches on a small fraction of the things you can do to help make your game run better in Unreal Engine 4. While I couldn’t possibly cover every aspect, there are still a few smaller tips and tricks which you can follow to help keep your game running smooth. I just have them listed below in bullet form.

  • Reduce these:
    • Overdrawing
    • Dynamic Lights
    • Draw Calls
    • Shadows (These really kill performance so only have them when necessary and try to reduce how many shadow casters there are if possible)
    • Material Instructions
  • You can turn things off while in game with the command show (i.e. show particles). You can also do it through the editor in the top left where it says show. Turn off things that you don’t need while looking for a specific problem to help narrow it down quicker.
  • Use stat unit & r.screenPercentage 10 to help determine if you are CPU bound or GPU bound. If your FPS goes up, you are GPU bound. If it stays the same, you are CPU bound.
  • Make your UI event based instead of binding (binding kills your performance, especially if used often)
  • Take a look at Epic’s documentation for Unreal Engine 4! There is a lot of really good information there and it is only getting better with time.

StyroBotPy

About a month ago, I started a new project which really piqued my interest. It is rare for me to find a passion project where I don’t want to do anything but work on it. But this one in particular really had me going and for 3 weeks, I worked on a project that my friend had originally created. This project was called StyroBotPy. StyroBotPy was created by a friend of mine in C# to be a Discord bot. This bot had various functionality such as being able to talk to cleverbot in Discord chat, playing music in the voice channels, getting quotes from a text channel and more. Unfortunately for him, something in the C# API for Discord broke the night before his project was due and he re-wrote it in Python. This was all before Discord even had an official API (which it does now).

This project interested me because it was a neat idea; and since I use Discord, I thought it could be cool to mess around with this on my own. So with his permission, I became a contributor on his project and came up with a grand plan for changing it. Now, the original project was nicely structured and setup to be fairly modular, but when it was hastily re-written in python, it was messy and basically a god class. It was quite the mess and the interwovenness of the code plus the implicit nature of python made it somewhat difficult to decipher at first. But this only made it more fun to work on. And so I set off on my journey to refactor and update his Discord bot.

For about a week, I was playing around with an idea of turning the entire thing to a Plugin based architecture. This meant making it extremely modular and super easy to extend in the future. Add on top of this some of python’s quirks and you’ve got a pretty great system. The only problem was that the project in its current form wouldn’t work well with this. It was mostly because the repo and the code wasn’t really setup for multiple files. If you’ve ever done python development with more than 1 file, you will understand how it can be a problem when your project isn’t properly setup. I was also working in linux and he created the python in windows. Add on top of this the fact that there was no automation like make/batch. It was a nightmare. So I ended up spending a few days restructuring the repo and creating some automation that would allow me to have a decent workflow. I tried my best to make sure it still ran on windows, but I honestly still have no idea if those batch scripts work. I kind of abandoned the windows specific stuff to focus my efforts on the python itself.

Once everything was setup, I began experimenting with the Plugin architecture and after a bit of researching, I found a solution that I liked a lot. I am using a python module called yapsy which is short for Yet Another Plugin SYstem. It allows me to very easily create plugins and load them dynamically at runtime with almost no effort at all. And on top of this, it is built on Python’s standard library meaning it has no dependencies of its own, making it light weight and simple. Once I had found this, I had what I wanted working in minutes. Then over the course of roughly 2 weeks, I slowly tweaked my abstract Plugin class to hold the functionality I needed for the system. The result can be seen below.

The comments explain everything fairly clearly, but the basic idea is that a Plugin has all the functions it needs to do things based off of input from Discord. With this simple but effective Plugin system created, I began refactoring the codebase into plugins.

It took a little bit of time, but I eventually implemented 5 different plugins. They each show off different things you can do with the system, but they also have useful functions from the perspective of a bot. I will talk about each one individually so that I can talk about some of the interesting things about them and any challenges I faced.

CleverBot Chat

To start off, I will begin with the Cleverbot plugin. This was one of my favorite parts about the bot before I started working on it and I knew that implementing it was a top priority. Luckily for me, there was a python module for cleverbot and it was something that took less than 5 minutes to implement. The idea for this plugin is that with a specific command, you could talk with cleverbot and the bot would post the response to the channel you sent the command in. The result was spectacular and you can see an example conversation below.

1

Quotes

The next plugin I would like to show is the Quotes plugin. This plugin was designed based off some functionality the original C# bot had which would let you say messages from a specific text channel. The intent is that you create a channel for memorable quotes and then at any time you can have the bot read a random quote from this channel. When converting the bot to python, this feature got lost and I wanted to make sure it lived on. But making sure it lived on wasn’t enough, I also wanted it to be more flexible. The previous implementation had hard-coded channels and that made it so only 1 channel could be used for quotes and you couldn’t change it without modifying the python script. I wanted to make this more modular with a server side solution so that even if the bot was run on a different machine or by a different person in the same server, it would have the same settings. I eventually came up with the idea of storing this information in a text channel. This solved the problem, but it isn’t perfect. I will talk more about its shortcomings later in this post. The result of all of this was that the plugin was able to give you quotes from a channel (you could change which at any time) and it would remember this information across sessions and computers for that server. You can also see it in action below!

2

Music

The next plugin I want to talk about was also a feature of the original bot. This is the music plugin. This plugin allows the user to download and play music playlists in the voice channels in Discord. You just simply tell the bot to enter a specific voice channel, queue up the songs and play. These songs are local to the machine the bot is running on, but you can always download songs through one of the commands. This would download the youtube video you specified and save it as a mp3 which would then be used for playback later. This was originally used to create playlists in the voice channel so that you could listen to Mom’s Spaghetti and other great songs while talking with friends or playing games with them. Below you can see the bot in the voice channel General playing the song Starfall which I downloaded and queued to play.

3

4

 

High Roller

The second to last plugin I want to talk about is a new feature to the bot and was created to help show how the bot is capable of doing just about anything, such as dice rolls. This plugin lets you do typical things like roll a dice of any size or flip a coin. The result is obviously said in the chat and this could be used for things like your weekly D&D with friends or perhaps even to settle disputes such as who is the best high/low roller. Another small feature is the ability to call a coin flip before it happens. If two users do this, the coin is then flipped and it will tell you who won/lost. It is possible for everyone to win or lose depending on what the two of you called before (you don’t have to call different things).

6

5

ChatMod

The final plugin I created is also a new feature to the bot. This plugin handles chat moderation based off criteria defined by the server admins, specifically based off of banned words. The bot stores this information in a text channel, just like with the Quotes plugin so that it persists between sessions and machines. It also supports other settings such as how many warnings a user gets and whether to kick or ban them if they have too many infractions. The plugin is also fairly good at scrubbing through text to find words that users try to hide. It is capable of stripping out all the markdown that Discord supports, as well as other common things such as hyphens to better determine when a banned word is used. It is by no means perfect, but this plugin tries to show how one might create a plugin which doesn’t run off of commands but parses messages directly to do an action, such as moderating chat. As you can see in the images below, I have a message with a bunch of markdown which still finds the banned word (in this case, “poop”) and warns me. The plugin is also nice enough to tell you when you’ve reached your last warning before it takes action.

7

8

The Server Side Problem

Earlier I mentioned that my current server side solution has problems and isn’t very good. What I mean by this is that for starters there is no established way of doing what I want so its kind of “hacked” together. It is also not supported as a feature in the bot itself, but is instead done by the plugin itself which has drawbacks. Not to mention that in its current form, the bot doesn’t handle multiple servers very well at all.

Looking Forward

While there may only be 5 plugins currently implemented, I know I have a few more ideas that given the time I would love to add. Things such as an improved High Roller plugin which allows for a loot system similar to World of Warcraft’s Need/Greed system and making the roll use dice notation so you can specify 2d6 or something like that to roll multiple dice like you would need in a lot of roleplaying board games. I also have other ideas such as improving the help command and adding a system to help disambiguate between commands with the same name. I would also like to create a better, more in-depth server side solution for storing settings that plugins can easily use through the bot instead of having to “hack” it. I could go on and on, but I think I made my point.

Reflection

Every time I think about this project, I get excited about the potential features and all of the cool things I could do to improve the system. During the 3-4 weeks I was developing this constantly, I learned a lot more about python, but more importantly I had fun. I had the opportunity to explore something I’ve never done before and looking back, I never expected to like it so much. My hopes are definitely to continue working on this to see where I can take it and perhaps it will even become an interesting portfolio piece down the road. I also think that there is a lot of room for improvement. While building this bot, I experimented with a lot of structural things and the further I progressed, the less I implemented due to time constraints. My hopes are to return to this project in the near future to continue developing it on the side.

 

Check this project out on Github!

Gold Master

Senior Production

Post XXI


This will be the final blog post for capstone. I will be writing a post mortem in the future for this project, but otherwise there will be no more updates. Since my last update, a ton has changed in our game. If you took a look at our game less than a month ago and took another look at it today, you would be blown away. With that being said, however, it makes it difficult to talk about what specifically I did. These past 2 weeks in particular have been so filled with production work that my memory is all melted into one big ball and I can’t really remember specifics. I do know that a lot of my time was spent making builds, testing, fixing bugs and implementing last minute “features” which were necessary for our game. This past weekend in particular saw 25+ hours of work put into it from myself as well as similar hours for many of my team mates.

One of the goals that we were supposed to hit for the senior show is “Gold Master”. Basically just meaning a stable and “complete” build of our game. And by complete, i just mean that it is fully playable from start to finish and has all the art, systems and design we wanted to have in the game. Obviously its impossible to get this because things never work out how you would like them to, but given what we accomplished, we definitely reached the spirit of what Gold Master is.

With our final build submitted and the senior show coming up this Friday, the team is now shifting gears towards preparing for the show itself. Luckily for us, most of it will involve showing off team and individual reels. Afterwards, we get to spend time talking with people about our game as they come to play it and learn more. It should be an interesting experience and I hope that it all goes well.

Our team’s reel can be viewed below. It honestly is more like a teaser than anything, but it should give you a decent grasp of different aspects of the game. It has puzzles, monsters, narrative and cutscenes.

 

This is all I have to talk about in this post. I will be making a post mortem post in the future (not sure when yet since i’m very busy). We also made a page on itch.io which you can check it out here if you want to download and play the game or find out more about it!

TL;DR:

  • We hit Gold Master
  • There was lots of crunch
  • Senior show is Friday
  • Post mortem coming soon to a blog near you

Beta Crunch

Senior Production

Post XX


Recently I have been swamped with work between deadlines at work, deadlines in production and my already busy schedule. But in this madness, some good progress has come for the game. Last time I talked about the Breaker Box system for the game and some of the things I had done for it. But the biggest problem this had was that it was all visual and was not in any way functional as a system. After some complications with integrating it with the circuit system we have, the Breaker Box is finally in a completed state. This isn’t the only thing I’ve done though. I’ve also spent time making builds, bug fixing and polishing features.

The Breaker Box system was much larger than I had originally anticipated it to be. It also to some extent slowed down our progress a little bit which is unfortunate. But now that it is fully functional, it gives our designers the ability to fully implement our levels. So what does this functionality include? I think this GIF will be able to show it first and then i’ll explain what happened. (Please excuse the terrible GIF quality, i’m bad at making these)

breaker_box

What you’ll notice is a few things. First, when you interact with the breaker box, the door animates open and you can see a light turn on. Then you can also notice that the mouse cursor appears, indicating that the controls have switched to mouse controls unlike the normal controls seen in the game. When i mouse over switches, they highlight and clicking on them flips them on/off. You can also see that when I flip the top switch on the first time, it turns off all the switches. This is showing what happens when the circuit is overloaded by too many things being on. Then when I flip the switch again, you can see the gate in the background starting to lift. When i toggle it back, the gate drops because the power has died. Finally you can see the door closing and the light turning off as the controls go back to their previous state. During this whole process of interacting with a breaker box, you can’t move and your camera is stationary. It might not seem like a lot, but this is a fairly large system which was nearly more trouble that it was worth due to the circuit system and its “problems”.

Beyond the Breaker Box which is finally complete, I also spent time doing bug fixes and polishing features. Since we’ve been doing a lot of crunch lately to meet our upcoming deadline of April 25 (when the final build is due), I’ve been making a lot of builds for QA and class. Unfortunately, due to our workflow, we don’t have an easy way to do something like continuous integration or even setting up a build server to handle it for us. This means I’ve got to do it manually each time. And since it would be too easy for things to work on their own, the build always has problems which I need to fix before I can release it to the team. Most of the time, they tend to be bugs which crash the game, but sometimes its because a feature isn’t working as intended or because its just completely missing for some reason. This is probably my least favorite part about working on this project, but it is necessary and helps move our game forward.

I mentioned in the previous paragraph the deadline of April 25. This deadline is when our class requires us to have a final, stable and complete build of our game. What this means for us as a team is that we have roughly 3 weeks to make sure that everything is in, working and feels good. This isn’t really a lot of time, especially since we only just recently became feature complete (our narrative, art and audio isn’t even all in yet!). It is going to be a long crunch these next three weeks and all of us can feel it. The good news is though that once that day hits, we are free from the crunch and will have a few days to relax from the pressure before the senior show which is on the 29th.

This is all I will be talking about in this post. I will probably be making only 1 or 2 more updates before the 25th depending on what gets done by me and how busy I am. This will all be followed by a post mortem after everything is over, including the senior show.

TL;DR:

  • Breaker Box is done
  • Fixed bugs and made builds
  • Lots of crunching…
  • Deadline is in 3 weeks

 

PDGenerator

Roughly 8 weeks ago, I started a project which seemed interesting and required some thinking. I purposely decided when I started that I didn’t want to lookup how to do something like this in an effort to see what I was capable of coming up with. I knew there would be problems which I had never tackled and it was a great experience to learn as I went, improving my abilities to solve these complex problems. What I created in this time was a thing I have decided to call PDGenerator. PDGenerator is a static API for creating procedurally generated dungeons in C++.

The approach I took for this was inspired by the dungeons created in Runescape for the skill Dungeoneering. In Runescape, they generate the dungeons in a very grid-like fashion.

A map of a Large dungeon in Runescape.
Image Courtesy of Zybez.net

Having played a lot of Runescape, it was easy for me to come up with some basic rules to use for the algorithms needed. I have put them in a bulleted form below.

  • A dungeon should always be a grid. The width and height of the grid don’t need to be the same.
  • Rooms can only connect in the 4 cardinal directions (North, East, South, West)
  • Every room should always be reachable from any other room (directly or indirectly).
  • The dungeon should always be fully solvable.

This of course doesn’t encompass the features I was looking to have, but they were guidelines to keep my end result focused and served as a baseline for testing as I progressed through the project. Since I was already basing the basic rules for the dungeon generation on Runescape, I decided to also base some of the features off of the game as well. In particular, the use of locked doors and keys where each door/key combination is unique. This made it tricky towards the end when I was generating keys for the doors, which I will go into more detail about later.

I would like to spend a little bit of time in this post to go over the various components of the generator and while this won’t encompass all the details, it will broadly go over the important parts. To start this off, I am providing two code snippets. The first snippet is the BuildDungParams structure which contains the information needed to create a dungeon. The second snippet is the BuildDungeon function in the API.

I will avoid mentioning the individual values in the BuildDungParams structure because I have them nicely commented to explain their functionality. This brings us to the BuildDungeon function which I have provided. Before we dig in too far, I would like to point out that I have some typedefs such as pd_dung_ptr and I will do my best to include these typedefs at the top of the code snippets when they are used in the code snippets. I will now breakdown this function into its parts and talk about each one in more detail. To make things easier to explain, I will be using a 5×5 (25 room) dungeon as an example throughout this process.

Random Seed

In the settings for the dungeon, you can specify whether or not to use a custom seed. This is to allow the user the flexibility of creating a dungeon using a specific seed or to do it truly randomly. The generator always makes sure to seed the rand function to avoid problems such as the user forgetting to.

Create Dungeon

This function is fairly simple so I won’t show a code snippet but i’ll briefly summarize it. It creates a dungeon of the width and height specified by the user. It then populates the dungeon with rooms based off this width and height. These rooms are based off the room settings provided by the user in variables such as RoomMinWidth and RoomWidth. If the min and max are different, it uses a range, adding some randomness to the room size. It returns the result of this process as a pd_dung_ptr. In the case of our 5×5 dungeon, we will be getting a dungeon with 25 rooms in a grid something along the lines of this.

1

Connect Dungeon

The goal of this function is to generate the connections for the dungeon. Up to this point, we only have a dungeon with rooms that are not connected to anything. This function takes in a dungeon and creates connections for the rooms. This will guarantee that every room is connected to at least 1 other room and that every room can reach any other room. I have provided pseudocode below due to the complexity of the implementation.

Given our 5×5 dungeon example, you could expect a connected dungeon to look something like this. In this particular case, I had a setting which was adding a few redundant connections during the algorithm to improve the connectivity of the dungeon.

2

Seed Dungeon

I created this function as a way to help ensure that a dungeon can have more connections than what the ConnectDungeon function gives. Since we are dealing with RNG, you never really know how it could end up. Worst case scenario, its just a really long winding hallway. This function calculates a number of connections to add (dungeon size * percent), picks a room, picks a random neighbor and adds a connection there if one doesn’t exist. You can also tell it to enforce the number it calculates to add which basically just means it will guarantee that many are made (unless you hit the max number of connections in the dungeon). If we were to seed our 5×5 dungeon example, we might now have a dungeon that looks something like this.

3

Create Locked Doors

This function is also fairly simple. It just gets a list of the connections, calculates how many locked doors to add (num connections * percent) and adds that many locked door to random connections. This function is always enforced, but like before, it will stop if it hits the max amount of locked doors. If we took our 5×5 dungeon example, we might see something like this.

4

Create Keys

This is either the first or second most complicated function for the generation. What made this tricky is ensuring that a dungeon is always fully solvable. I’m sure there are lots of great ways to do this, but I decided to take an approach similar to a flood fill algorithm. The goal is to get all accessible rooms from a starting point and pick a random room to spawn a key in. I have provided some pseudocode below. Just keep in mind that this leaves out some details.

If we were to visualize this with our 5×5 dungeon, you could expect something like this. In this particular case, the seed I was using didn’t do a great job of placing the keys. The algorithm also doesn’t discourage placing more than one key in a room which you could see as both good and bad. Regardless, this dungeon should be fully solvable and is ready to return to the user in the form of a pd_dung_ptr.

5

Notes

The dungeon itself tries to store the data as separately as possible. The goal is to keep things as decoupled as possible, making it easier to deal with the data. A dungeon stores an array of rooms. These rooms only know their grid position, if they are the start of the dungeon and what keys (if any) they have in them. If this were to be expanded further, they might also contain information such as what the room contains (such as items, monsters, the layout, etc).

The dungeon also stores the connections in an array. Connections just store which two rooms are connected and if that connection is locked. Because these are stored in an array, it means that finding a connection for a room could be time consuming. To counter this, the dungeon also has a lookup for connections. This lookup stores a reference to the indexes of all the connections a room has, making it quick and easy to grab a connection for a room. Since a connection also stores if it is locked (aka the locked door), I implemented a lookup for these locked doors which makes it quick and easy to find which connections are locked. Granted, this lookup wouldn’t do much if a large amount of connections were locked.

The dungeon also provides a ton of helper functions for accessing information that is stored. Anything from finding rooms, connections, locked doors, room floods and so forth.

The dungeon also has the ability to export itself to JSON. This was useful for debugging and also makes it a convenient way to export the important information in the case that you want to create your own storage objects for the data or want to save it to a file or even use it in an external application.

Reflection

Looking back on this project, I was able to accomplish a lot in the roughly 8 weeks I had. I also learned a lot about how to generate a good procedural dungeon (something that I think I was not able to accomplish). In particular, the way I did the generation made it difficult to intelligently layout a dungeon and if I were to change things, I would try to incorporate many of the things I did for generating a dungeon as part of the process of connecting rooms. There are a few other tricks like this that can help make a dungeon more interesting to traverse and explore. One thing I wish I had spent time on doing was incorporating dead ends to the dungeon. Currently, the only time there is a dead end is if the room connection algorithm got unlucky in the RNG and this doesn’t really count.

Pre Alpha

Senior Production

Post XIX


It has been a little while since I’ve made a post about my senior production team so I felt it was necessary to bring an update on my progress. These past few weeks have been interesting to say the least. Last week I was at GDC so I was unable to do any work and the week before was a lot of time spent on my other classes (in preparation for GDC). Not a lot has happened in the production space, but there are some features and upcoming deadlines worth mentioning.

Before I went to GDC I was working on the new Breaker Box system. While this system is still incomplete, it has progressed enough to warrant more information. I spent a lot of time thinking about how I was going to implement the system because a large majority of it needs to be completely dynamic. Since no two breaker boxes are guaranteed to be the same, the goal was to cut down on the amount of work a designer would need to do to both create new Breaker Boxes and to modify existing ones. While thinking about this, I remembered my solution for the radio conversations and it sparked an idea. I tried a few things but eventually settled on this solution.

27

My biggest disappointment with this is that there is no easy way to store an array of structs while still providing nice editor access in Unreal. Not without making modifications to the engine and that is unfortunately not an option due to workflow concerns (as well as the time commitment needed to create this). Nevertheless, it works well and I even went a step further to provide the designer with safeguards incase they made mistakes. For example, the breaker box always verifies the settings before creating everything and It gives out helpful errors to the log which say what is wrong. The process to create a breaker box is fairly simple and is just 3 steps.

  1. Create a breaker box in the level
  2. Create a Blueprint class inheriting from BreakerBoxSettings and customize the properties available to you (as seen above)
  3. In the properties for the breaker box you put in the level, tell it to use the settings class you just created with the combo box

The result of this can be seen below!

28

The next big step is to hook this up with the circuit breaker system. This is a work in progress and as of this writing isn’t complete. This would make the system fully functional in terms of the functionality the breaker box is supposed to have. However, there is also a huge part of the breaker box missing which is the way a player interacts with it. Unfortunately, this system hasn’t even been started and will take a bit longer due to needing a new interaction system. More info on this will be given in a future post.

I have also spent a little bit of time since coming back from GDC doing bug fixes for the game. Some of these have been outstanding bugs which have gone from sprint to sprint without being addressed due to being minor inconveniences and not game breaking. Others were newer and impacted gameplay systems. The most notable of these bugs was a bug with dropping items (in this case, we were dropping flares). Dropping a flare which had 50% of its energy gone would cause future flares that you used to start at 50% energy instead of 100%. This is obviously a major problem for gameplay and after half an hour of stepping through code using the logs for guidance, I was able to fix it. The reason it is notable is because the cause was due to a problem with the order of operations for dropping an item which would cause it to retain information on accident.

At the beginning of this post I mentioned upcoming deadlines. This could probably be figured out from the title of the post. Next week we are challenging the Alpha stage. This means that this coming week will be a huge crunch to make sure we are feature complete. This is only the start of the crunch though because for the next month or so (until the senior show at the end of April), we will be challenging a stage each week. This will be a tough month for all of us and hopefully none of us go crazy in the process.

This concludes my update for this week. I will hopefully have more to talk about next week with Alpha.

TL;DR:

  • Went to GDC
  • Started implementing the new Breaker Box system
  • Fixed some lingering bugs
  • This next month will be crunch
  • Challenging Alpha next week!

Slowdown

Senior Production

Post XVIII


This week’s post will be short and uneventful but i’ll give a quick status update. After a long, crazy week with the Montreal Game Festival, we have slowed down a bunch and priorities have shifted. This week hasn’t had a large amount of progress on the programmer side due to an upcoming due date for an assignment in another class which every programmer is currently worrying about and scrambling to finish. This isn’t to say nothing has been done though.

This week we got a lot of small features in such as a new Light Actor system which will allow the designers to place lights in the level (our special actor for this) and it will already come with useful features such as a mesh, the light, direct integration into the circuit system and so forth. It will make the process of creating the updated level 1 a bit easier in terms of setting up the lighting system. Item Dispensers have also seen a slight upgrade and they can now have set quantities available to be dispensed. They can also be destroyed upon running out which is a useful feature. This makes it more robust and can now be used as a general purpose dispenser in levels, without having to create a new blueprint explicitly for each item pickup. The monster has also had some slight upgrades visually and is now less smoky and more bug like (think bees).

Our group has also focused this week on meeting the Greenlight requirements. This is something specifically for the class which is required and is more or less a bunch of documents. It happened to work out nicely for the programmers as this meant we didn’t need to implement a lot this week, allowing us to focus our energy to the other 3 programming classes we have.

This is all I have to talk about this week. Hopefully this next week i’ll be able to show off a new system currently in the works which involves the breaker box.

TL;DR:

  • Not a lot of programmer features added this week
  • We are doing the Greenlight stuff
  • New Breaker Box system coming soon

Montreal Game Festival

Senior Production

Post XVII


This last week has been an important step forward for my team and i’d like to take a moment to talk about it. This past weekend, two of my producers and one of our designers took our game up to the Montreal Game Festival where we showed off our game, along with a bunch of other indie games. This meant that we had a very important deadline to hit and the build got a lot of work before the Saturday when the event occurred. During this small crunch, we as a team realized a few things and really got to see how we all work under pressure and tight deadlines. This ended up working out well for us and was an eye opener. But what did this mean for the build?

The original intent when we signed up for this event back in January was to show an updated version of our first level. This was something that we’ve been slowly working on but the keyword here is slowly. We hit a bit of a bottleneck and this delayed the level and we ended up realizing last week on Wednesday that there was no way we could get this updated version of the first level done in time. This is when we made the decision to revamp our existing level to better show off some of the new things we plan to pursue in our game. It meant removing a lot of old content and putting in brand new content that hadn’t been implemented before. It meant new art assets and new functionality all in the span of roughly 72 hours. The team quickly went to work on this and we got a lot done.

I personally was working on a new system in our game which involves a radio the player finds at the beginning of the first level. This radio is important to the narrative and revolves around having radio conversations with someone on the other end who is guiding the player. This meant two things for me.

1. We needed to be able to create conversations from sound files.

2. We needed to be able to play the conversations.

What I created was a robust system which is relatively easy for the designer to create conversations and play them. With it, I also quickly created a small radio which is what you pick up that initiates this part of the gameplay. Below I have put the class which I created for creating Radio Conversations just to show how simple it is. Essentially, it is just creating data which the RadioComponent uses to play sound files in a particular order with specific delays.

What makes this particularly interesting is that the designer can create these in Unreal’s Editor and easily play them. Just by creating a blueprint class which inherits from RadioConversation and setting the default values for the VoiceLines and VoiceLineDelays arrays.

25 26

Beyond this, I also spent time fixing bugs and managing the other programmers to make sure we kept our priorities straight and could meet our deadline. Overall, I think we did a great job considering how little time we had and it showed how dedicated to the project every member of the team was.

This is all I have to talk about and show for this week, but in the near future I will be posting a tutorial on how to use Git (specifically showing off TortoiseGit). This is intended for people who have never used Git before but is also there to serve as a guide for those who don’t fully understand how to do everything. Keep an eye out for this sometime this week!

TL;DR:

  • We had a small crunch
  • We took our game to the Montreal Game Festival!
  • I created a system for Radio Conversations

Merging

Senior Production

Post XVI


This week’s update encapsulates a culmination of work from this week and last week. I decided against posting something last week due to the low volume of work to discuss and show. Since my last post a bit of major changes to the game have been made and i’d like to spend a little bit of time talking about them. A good chunk of the updates weren’t done by me specifically as they were tasked to one of the other 3 programmers in our group.

The first major change is in regards to the monster and how it functions. Previously we were attempting to make the monster something that was very heavily controlled by scripted events and triggers to give the desired effect. This past week we’ve been pushing towards a complete overhaul of this system in favour of a monster which is closer to some of the original ideas proposed last semester. This of course means and AI controlled monster which actually has a physical presence in the level. This has some large implications and we don’t yet know if it will be what we want but I sure hope so. With this also came an update to the light system. The light system now uses the actual lights in the level to determine whether the player is in the dark or not and this has an effect on the behavior of the monster.

We also have been making some major pushes in the code base to refactor some of our blueprint to C++ and improving the usability of various systems to make level creation an easier process. This has been a group effort and has so far had good and bad parts. The good part being that now things have become a bit simpler and less complex due to the move to C++. The bad part is that in the process, there have been conflicts with merges as well as small bugs being introduced. Some of this could have been prevented, but what is done is done and we are addressing the problems which lead to this outcome.

My work this past two weeks has been mostly around the flashlights, refactoring and helping to manage the other programmers. This coming week in particular might have me being a bit busier with the push for the indie game festival this coming Saturday which my group will be presenting our game in. It is a bit scary since so much still needs to get done on the design and art side. I will also be creating a document which will help teach the team members who are struggling to use git in order to prevent some of the problems we encountered this past weekend with merge conflicts.

This is all I have to talk about in this post. Unfortunately this semester has less to talk about in my blog posts due to the separation of a small workload between 4 programmers but hopefully in the near future there will be more interesting topics to cover.

TL;DR:

  • Major changes to the monster
  • Major changes to the light system
  • Huge push to refactor Blueprints into C++
  • Lots of merge conflicts this past weekend

Let there be Flashlights

Senior Production

Post XV


This week has been very productive on the programmer front and there’s a little bit to talk about in today’s update. My task over the weekend was to prototype some flashlight functionality. For QA this coming Thursday, we wanted to test a lot of features and one of those are changes to the flash light. Since we aren’t yet sure which system we want to continue with, we have 3 flash lights to test. I’ll go into a bit more detail shortly. We have also planned to test out or newly created Kiosk mode. This will be what you see when you enter the game, with the main menu being displayed in front and it will also be what you return to if you should idle for too long in game. We also have an update light detection system which uses actual lights to determine if you are in the dark or not. Since I didn’t work on the systems other than the flashlight, i’ll focus on them.

The first flashlight we plan to work with  is just the flash light we have been using. It is meant to be more of a baseline from which to better gauge the new ones. It currently can be recharged by holding R and that’s is honestly all it does. The rest is automatically taken care of for you. The second flashlight is an improved version of this flashlight. It implements some of the features that the designer intended from the start, but never made it into the build last semester due to time constraints. For starters, it uses an active reload system to recharge the flashlight which currently requires you to enter this reload mode by pressing R (pressing it while in the mode will leave it). While in the reload mode, you have to alternate clicking the left mouse button and the right mouse button to recharge your flashlight. It also has the ability to turn the flashlight on and off with F which is a long needed feature. The last flashlight tries to utilize batteries to achieve a similar goal as the original flashlight. Instead of holding R to recharge it, you press R to consume a battery, automatically recharging your flashlight to full. This means that batteries would need to be placed in the level.

I also spent a bit of time working on an object which will make testing new items easier. It is an item dispenser you can place in the level and it allows you to specify how many to give you and a few other properties. It even lets you tell it what text to display on the object so you can know when you see it. This item is interacted with using our interactable object system so it even highlights when you are looking at it. An example can be seen below.

24

While this week was pretty good for the programmers (due to our need for features), the following week could prove troublesome. There are plans to implement a monster AI which will keep one of the programmers busy, there is growing concern amongst us that there isn’t enough work to split between the 4 of us. Hopefully we will be proven wrong but it is looking to be problematic. Next week’s focus will likely be on the monster and polishing up some systems like the flashlight further.

This is all I have to talk about this week, but there will be more to talk about next week.

TL;DR:

  • Other programmers made a lot of cool things
  • I made a lot of flashlight updates
  • I created an item dispenser!
  • We might not have enough work for 4 people