A. Main Questions
- Game concept: To what extent did your game concept change from initial concept to what you implemented? If it did change, how did it change and why?
Our final, finished game stuck pretty close to our original concept - a 2v2,
capture-the-flag dungeon game. There were no significant changes from conception to finalized demo.
- Design: How does your final project design compare to the initial design, and what are the reasons for the differences, if any?
Our final design also stayed basically the same to our initial design. We made some adjustments from the starting design as we expanded our code by adding an extra layer of indirection for the networking protocols but this happened early on and we didn’t have too many major design shifts after that.
- Schedule: How does your final schedule compare with your projected schedule, and what are the reasons for the differences, if any? (You should be able to glean this from your status reports.)
We tried to stick to the projected schedule as much as possible, and for the most
part we implemented features in the order we planned to. However, some milestones took longer than expected, so not everything was completed as quickly as we planned to in our projected schedule. Most of the features we wanted ended up being included, but delays from earlier parts of the project meant not everything got in. For example, we wanted to include a minimap in the game, but for some reason the game crashed at unpredictable points after its inclusion, so we ended up not using it for the demo.
B. General Questions
- What software methodology and group mechanics decisions worked out well, and which ones did not? Why?
Having source control and code reviews before accepting most changes made it more likely that problems with game logic or performance would be found earlier. Using Travis CI prevented a few instances where code would have only compiled on Windows.
Sometimes we assigned development tasks in a way that one person’s task depended on someone else’s being done, which led to delays on occasion. It might have been better to assign dependent tasks to the same person, when given the choice between assigning dependent and independent tasks, since it might have reduced the time it took for important tasks to be finished.
- Which aspects of the implementation were more difficult than you expected, and which were easier? Why?
[Ye] I didn't personally find most of the features we implemented to turn out to be harder than expected. There were some bumps but most of it was well within the range of my expectations. I think that if anything, extending various parts of our code turned out to be faster than expected because we thought about our designs beforehand.
[Medvinsky] Implementing the synchronization of object creation and deletion was simpler than expected, but we never made it so that the additional information sent for some created objects was created generically. Particles had some unexpected performance issues that needed to be solved. There is also some weirdness with physics that causes visible bouncing of the player when moving at high speeds, and we couldn’t determine the cause.
[Zhang, J] One aspect that was easier than I expected was texture loading. Since I actually already had part of the code in place when I started on texture loading, the only things I had to do were make sure I was using the library correctly to load the textures, make sure each vertex had its corresponding texture info, and edit the shader to draw the texture if the vertex had a texture. One aspect that was harder than I expected was making a 2D UI for our game because our game’s camera is not front or top down facing and therefore we would have to project our 2D UI properly to the screen or else it would look unnatural.
[Wang] Sound system is actually easier than expected. We first thought that we might need to handle a lot of channel stuffs and build up the system from almost scratch. However, sdl has a pretty good extension sdl_mixer which provides high level api for us to use. Physics system is harder than expected since bullet library is huge.
- Which aspects of the project are you particularly proud of? Why?
[Ye] The healer's particle effects were really cool. Leon was the one that actually did the hard work implementing the particle systems, but since I pulled an all-nighter to fix things and merge in several new game additions, I ended up adding a bunch of particle effects to the healer. Also among those additions for the last night, I personally added the last two mob types (ballerina and nutcracker), and I was extremely pleased at the player experience I achieved with some minor tweaks to the mob AI / movement dynamics.
[Ozawa] Personally, I’m pretty proud of the candle lights. It was a bit tedious trying to get them to work at first since it was just a lot of finding coordinates depending on the room type and offsetting them properly. After everything was done though, it was really cool to see how they looked in game and I thought it was a pretty neat addition to our game’s aesthetic.
[Zhang, J] For me, the part I am most proud of is the animations because I had never dealt with skeletal animation when importing a .dae file before, and therefore I had to do a lot of research on how Assimp parsed animation files in order to store both the model info and animation info for the model properly.
[Zhang, V] I am very proud of my models - I was pretty much given full reign on how our game should look, and as such I got to see all my creative concepts fully rendered in game. Considering I had no experience with 3D modeling or Blender at the start of the course, I am proud of what I was able to achieve. On a side note, my favorite model is the headless ballerina. I am also quite proud of the soundtrack I was able to to put in at the last minute - I’d never tried to compose music before, and the resulting product was exactly how I’d imagined it to be.
[Medvinsky] I liked the various systems I implemented, like timers, the object update system, and particle systems. They feel very clean for the most part, since they are a little bit removed from the actual game logic.
[Quach] It got messy near the end, but I liked some of our class systems like for character classes, mob classes, and our input manager. The way they worked made it very easy to add new things: new character and mob classes after the first were added pretty quickly and only depended on new character mechanics. Also, changing keys and what they mapped to (or adding new keybindings for new actions for instance) was also very easy to do.
[Wang] I liked the sound system and physics system we designed. We used bullet library as base for our physics system. Although the bullet library is large and hard to understand in a short time, we managed to build up a easy-to-use api. For the sound system, we used irrklang lib at first, but later on figured out that it is not open-sourced and we switched to sdl libraries and did a pretty good job abstracting a api.
- What was the most difficult software problem you faced, and how did you overcome it (if you did)?
In our branch with minimaps, which was only feature-complete the morning of the demo, we were experiencing unreproducible (potentially nondeterministic) crashing. We never fixed it and we used an earlier version for the demo.
- If you used an implementation language other than C++, describe the environments, libraries, and tools you used to support development in that language. What issues did you run into when developing in that language? Would you recommend groups use the language in the future? If so, how would you recommend groups best proceed to make it as straightforward as possible to use the language? And what should groups avoid?
N/A
- How many lines of code did you write for your project? (Do not include code you did not write, such as library source.) Use any convenient mechanism for counting, but state how you counted.
We used cloc (https://github.com/AlDanial/cloc) to count lines of code and ran it on our source directories (/src and /mains). In total, we had 7571 lines of code (not including 400 lines of comments and 2096 blank lines).
- In developing the media content for your project, you relied upon a number of tools ranging from the DirectX/OpenGL libraries to modeling software. And you likely did some troubleshooting to make it all work. So that students in future years can benefit from what you learned, please detail your tool chain for modeling, exporting, and loading meshes, textures, and animations. Be specific about the tools and versions, any non-obvious steps you had to take to make it work (e.g., exporting from the tool in a specific manner), and any features or operations you specifically had to avoid — in other words, imagine that you were tutoring someone on how to use the toolchain you used to make it all work. Also, for the tools you did use, what is your opinion of them? Would you use them again, or look elsewhere?
For model and animation loading, we used Assimp.
For texture loading, we used stb.
In order to give us an easy starting point, we used Glitter (https://github.com/Polytonic/Glitter) which conveniently links all these libraries together so that we don’t have to deal with writing the CMakeLists ourselves for each library, and we used the latest versions of these libraries on Github at the time.
For our models, we exported them as .obj or .dae files from Blender. We used .obj when we first started loading our models for simplicity. We switched to .dae for some models when we realized .obj file parsing was taking too long, and also for animated models because the .dae file format contains animation information.
Luckily, I don’t think we ran into any major issues with these libraries when loading models, textures or animations.
[Ye] For some reason .dae files (which are binary) sometimes didn't work properly, and just exporting them as .obj files (which are plaintext) worked. On a potentially related note, we also had issues with Vivian's exported image/sound files via our git repository, so my working hypothesis was that we had a bad interaction with git tracking binary files. We didn't end up debugging this too thoroughly, since we found easy workarounds (getting other people to commit image/sound files with git, and switching to .obj occasionally as mentioned).
[Zhang, V] I had some trouble when exporting animations from Blender - the walking animations gave me no trouble, but when I tried to animate the pendulums in the grandfather clock, they exported rather oddly in that only the pendulums were visible when rendered in game, and the rest of the model was missing. In the end it wasn’t too much of a disappointment, as the walking animations were top priority and were working, but it was still quite strange. However, as a whole, I quite enjoyed learning how to model in Blender, and the program is efficient and fun to work with once you get the basic hotkeys down. ([Ye] I think the incorrectly rendered clock was due to a animation bug that we ended up fixing later for different reasons, but we didn't remember to put the clock back in since that fix was made a few hours before the demo...)
[Medvinsky] I think there was some issue with the exported DAEs being rotated compared to what we expected, so we ended up just giving a rotation to models imported from collada files when rendering.
- Would you have rather started with a game engine or would you still prefer to work from scratch?
A game engine would probably have been preferable purely for the purpose of making a game, but it was an incredibly valuable experience to implement the game using much lower-level components.
[Medvinsky] I would have probably used a game engine, maybe Godot for its freedom.
[Quach] While working with a game engine would have also been useful experience itself, I actually feel like the learning curve while also trying to implement game logic on top of it would have resulted in taking a lot of time away from making the game how we would want it to be.
[Zhang, J] I feel like working with a game engine would have allowed us to potentially add in more features because we wouldn’t have to spend as much time dealing with some of the graphics or physics parts but I think the learning experience and the freedom we got was really good as well.
- For those who used a networking library (e.g., RakNet or Boost), a physics library (e.g., Bullet), or a GUI library, would you use it again if you were starting over knowing what you know now? Describe any lessons you learned using it (problems that you had to troubleshoot and how you addressed them) for future groups who may use it. If you did not use a library, judging from the experiences of the groups that did, would you have used it in retrospect?
For networking, we used rpclib. Since we ended up deciding on a fairly simple networking architecture given that we would only be developing for LAN, rpclib wasn't that much of an issue, but if we wanted to develop for playing over WAN (or wanted to leave open the option for extending later), it would've been better to use a somewhat more general-purpose library.
For physics, we used Bullet. Tuning dynamics was a little messy, although it wasn't that much of an obstacle. Since our game didn't really need any 3D dynamics (e.g. jumping, falling, ramps), it might've been simpler to use a 2D physics library, though.
[Medvinsky] Rpclib turned out to be somewhat inflexible, so I probably would use something else if I was starting the project again from scratch, maybe something like Enet? After the update logic was set up, we didn’t end up touching rpclib that much anyway, so I don’t think having a lower level library would cost too much development time other than initially.
[Wang] Bullet library is really powerful and fast. I think it can work as physics engine for most of the small indie games, so I would recommend it and use it again.
- What lessons about group dynamics did you learn about working in such a large group over an extended period of time on a challenging project?
It’s important to stay in communication, especially if the work of different team members depends on each other.
- Looking back over the past 10 weeks, how would you do things differently, and what would you do again in the same situation?
[Ozawa] It couldn’t have been helped too much since it took a while for us to implement other classes, but if we had more time it would’ve been nice to think over balance for the classes. The basic warrior that we had felt pretty underpowered compared to all the other classes we included. Given we had a lot of other pressing features to prioritize, it might not have been very plausible, but it would’ve been cool to ponder over how to make the classes more balanced and (as stated by others below) playtest more to see how these things work out in practice. Personally, asking for help a bit more probably would’ve been good. There were times that I stared at my code pondering for a while and then one of the others had a pretty simple solution once I gave in and asked for help.
[Medvinsky] I’ve been having some wrist / arm issues, so I might have paced my programming so that the strain per day was lower. The desks in 220 and 210 are sort of high too, so I could have used my laptop on my lap.
Also I agree with the comments about playtesting below. I think the PvE parts of the game ended up dominating the PvP portions, which could have been tweaked with earlier playtesting.
When the initial sound implementation was turned into a PR, I had a problem with it due to the licensing of irrklang. I knew it was being used earlier, so I should have looked it up and checked its license before sounds had already been implemented.
[Ye] I would've gotten everybody's phone numbers week 1 so I could call them to make sure they went to sleep before 3AM and get to the labs just a little earlier than 3pm. (Yes I'm a hypocrite) Jokes aside, I would probably have double checked to see who was available when every week. Assigning tasks to the wrong persons at the wrong times, especially considering dependencies between tasks, delayed a number of features. For the demo specifically, in retrospect it would probably have been better if I had done the commentary on the actual gameplay.
Also, I think we should have decided on a programming language other than C++ that either everybody knew or that would be easy for everybody to pick up. For future groups I'd recommend strongly considering using a language like Java or C#.
[Quach] For me, I wouldn’t (and couldn’t) change much of what I did. I spent my 2 free days and other extra hours in the lab working on this game and any slowdown was unavoidable as I puzzled out game logic or adjusted to code or dealt with other class assignments or whatnot. As below said, however, playtesting early would’ve been very useful in figuring out how to balance our classes.
[Zhang, V] I would’ve pushed for playtesting our game earlier and more often - there were some things that we only noted as we playtested, and most of our playtesting was only done in the last few days, when there wasn’t much time to make any changes to our game design should we dislike something or feel that something was missing.
[Zhang, J] I wish I communicated better with other people regarding some of the features that I was working on. I also wish we allocated more time to playtesting as everyone else mentioned above.
[Wang] Overall the past ten weeks is ok. I could have pay more attention to the license of the library I used to avoid doing redundant works (like replacing libraries)
- Which courses at UCSD do you think best prepared you for CSE 125?
[Medvinsky] CSE 160 helped in caring about performance. I worked a little bit on graphics, so having taken CSE 163, 167, and 169 was helpful. The geometric / kinematic knowledge I gained from the graphics classes also helped in implementing the game physics, including knockback, attack collision shapes, and raycasting for mouse aiming. CSE 110 and CSE 120 gave some experience on implementing systems. CSE 130 provided familiarity with and the desire to use fancy stuff when programming.
[Ozawa] For me it would definitely be CSE 167, since I worked primarily on graphics and that’s essentially the only graphics course I took. It definitely familiarized me with OpenGL and some of the websites I looked to when writing code for the game were also resources I used when I took the course.
[Ye] Since I haven't taken nearly as many graphics classes as our resident experts, I'd say that taking CSE 167 was pretty invaluable. Without that, it would've been pretty much impossible to meaningfully work on or discuss the graphics code. Since I was organizing everybody's various contributions, making small changes to their PRs, and discussing design with them, the graphics knowledge I had from 167 was pretty much required. Other than that, I think CSE 100/101 are useful just for the fundamentals for reasoning about performance (most of the time performance wasn't an issue for us, but I attribute that to the fact that we only cut corners when we felt comfortable that it wouldn't be an issue), and CSE 120 was useful since that was pretty much the only class I took that discussed multithreaded programming in any depth.
[Zhang, J] As someone who primarily worked on the graphics, I would say that CSE 169 and CSE 190 Virtual Reality were what prepared me the most. Even though I learned OpenGL in CSE 167, these two courses were what really helped me solidify my understanding of rendering in OpenGL.
[Zhang, V] Since my primary role was that of an artist, I can’t really speak to any CSE courses that have prepared me for this class. I was learning Blender on the fly as we worked on this game in our 10-week schedule, so I suppose the most I can say is be sure to learn quickly for anything you may want to do or implement. For the art-side of things, practice practice practice, and draw inspiration from anything and everything you see (I mainly drew inspiration for this game from anime and gaming).
[Quach] Not exactly super important concept-wise, but courses like CSE 100/101 and basically core classes that provided both experience with C++ as well as just thinking about code and how to get things working were all useful. CSE 124 was useful in helping me think about how our network should, well, work. Though I wasn’t working on graphics, at some point I think classes with that might’ve actually been useful for when game logic crossed over to the graphics side and near the end when most of the things we needed were graphics-centered issues. Mostly though, just having coding experience was the most valuable thing in keeping me afloat.
[Wang] I think CSE 100/ CSE 110/ CSE 112 best prepared me for this class. In CSE 100, I learned a lot c and c++ stuff and in both CSE 110 and CSE 112 I learned a lot how to successfully cooperate with others.
- What were the most valuable things that you learned in the class?
[Ye] Mostly I learned lower-level details involved in using OpenGL/Blender, Bullet, and C++ for implementing our graphics and physics systems and overall code infrastructure.
[Ozawa] Working on graphics definitely gave me the chance to do more nifty stuff with OpenGL. Some of the basics were already there from taking CSE 167, but actually incorporating those ideas into visual effects for a functional game was really cool. I think working on the game also definitely helped my C++ skills, since I was a bit uncomfortable with it compared to Java and I learned some things about the language I probably wouldn’t have been exposed to if I wasn’t working on the game where optimization was an important consideration.
[Zhang, V] Blender! I was a complete newbie to Blender and to 3D modeling in general when I signed up as an artist for this class. The first warrior model took me a week to do in terms of fine-tuning the clothing and all the little details - in contrast, the mage model took me maybe 5 hours or so. I have some artsy friends who are interested in Blender for their personal projects, so perhaps I’ll be able to put this newly-learned skill to use!
[Quach] Just the experience of working in a group on a real-world software project was valuable. I got to learn the areas where my code was especially weak in code review and areas where I learned to optimize especially in regards to C++. And, of course, how to make a game.
[Medvinsky] I got a good idea of the level of work involved in developing a game, and what it takes to implement the systems that might normally be part of a game engine.
[Wang] Making game is hard but fun!
- Please post four final screenshots of your game on your group pages for posterity. I will display them on the group web page.
[pre-alpha]
C. Additional Feedback (Optional)
- What books did you find helpful that were not on the recommended list but should be? What books were on the recommended list but were not useful and should be removed?
N/A
- I will be teaching this course next Spring. What advice/tips/suggestions would you give students who will take the course next year?
Start early, start often.
[Ozawa] It might be a little obvious, but try to be realistic about your goals. Going in I thought we had a pretty reasonable schedule, and for the most part we did include what we intended to, but just know that things will very probably take longer than you expect with learning curves for what you’re working on as well as whatever other classes or outside responsibilities you might have. Don’t force yourself to follow an unreasonable schedule or it could be pretty hard on you. Also, communication is really important! Sometimes it can be hard to know everything that’s going on with the other areas of the game, so if you have concerns then make sure to ask and don’t be afraid to get clarity about anything. It’s a lot more reassuring to not be in the dark about anything and your teammates will be willing to help you if something isn’t going as expected.
[Ye] For concrete tips, I'd strongly recommend using design patterns that break compilation dependencies (e.g. the pimpl pattern), dynamically linking libraries, and implementing a basic config file system of some kind early on. We didn't end up doing these, and over the course of the quarter, the amount of time we wasted on waiting for compiling probably added up to quite a bit. (For the compilation dependencies, following my earlier suggestion of using a language would make that point moot.)
[Medvinsky] If you’re going to be using some system a lot, design it well and make sure it is easy to use. It will make development faster later on. Also, try to assign related tasks to the same person, since they will remember more about the things they worked on recently. Pin down early on how you want your game to feel, because it will be easier to determine whether or not you want a particular game mechanic, and you can plan your mechanics so that they interact together in interesting ways.
[Quach] Communicate! We had an almost constant back-and-forth on our discord (sometimes at suspicious hours but it was useful) and we met up very often to just work together. This meant we knew when things were stuck or when things were going. If we hadn’t talked as much I think things would’ve been a lot more of a nightmare.
[Zhang, V] Figure out what your design and game aesthetic will be from the very beginning. We had a bit of a hiccup in the early weeks where most of the group was very neutral on what the game should look like, and as such I was somewhat confused on how I should design the models. Once I realized that the aesthetics side of the game was pretty much all up to me, I quickly pinned down an aesthetic and designs that I wanted and made sure not to diverge from them. Relating to this lesson, have the initiative to take control. Also PLAYTEST PLAYTEST PLAYTEST.
[Zhang, J] Definitely ask your group members for help if you run into any issues because they may have come into the same issue in the past so know how to fix it, or they may be able to provide a different perspective that will be able to help you fix it.
[Wang] Make sure you spend enough time choosing the best libraries to use!
- How can the course be improved for next year?
Please don’t make it a morning class, 9 am is a difficult time for CS students to achieve.
- Any other comments or feedback?
Thank you very much Professor Voelker, for teaching such a class and being very supportive of all our game designs and ideas. This class was a great experience and taught us a lot.