Final Report


A. 

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?

The initial core concept of our game was to make a chaotic, multiplayer, party game. We wanted the game to have a general “beauty pageant” theme where players would be competing in the pageant to determine who is the king/queen of the beauty pageant. All players would be fighting over a single crown, and whoever could hold the crown for the longest amount of time wins the pageant. There would also be extra game-play elements that would hopefully make the game more interesting like (1) having the players’ makeup run and obstruct their camera view so they would have to “touch up” their makeup, (2) there would be a “scare” mechanic to stun the player holding the crown that would paralyze players for a few seconds, (3) players would leave behind a “slime” trail that would slow down other players that got stuck in the trail, (4) some hiding mechanics like a smoke bomb to create areas for players to hide. All of these ideas would be combined with another idea to make a car themed game. 

What we ended up making was not super dissimilar from our original proposal. A lot of the elements still exist in the final game. However, we originally planned for our characters to have a cute and scary version of themselves in order to create a “horror” aesthetic and to create a large discrepancy between the two versions of the character for more visual interest and a larger comedic effect. We ended up making our player models cars instead of anthropomorphic animals or humans. We made this change because we weren’t particularly attached toward any one character design. In addition, we wanted to have a racing game and our artist was passionate about creating car models.

Design: How does your final project design compare to the initial design, and what are the reasons for the differences, if any?

Our initial design planned for our game to have stealth mechanics so that players could hide from each other and surprise the crown holder.

In addition, speed differences were much more of a focus. The crown holder was originally going to move noticeably faster than the others.  To balance this, players without the crown were going to leave a trail behind while walking that slowed down other players.

We also wanted to have a game mechanic in which players could be pushed off the central arena and would need to drive back up from a lower arena back to the central arena. 

In contrast, our final design did not have any stealth mechanics, because we wanted the game to be more fast-paced. We still gave the crown holder a speed boost, though it was a minor one (10%). The trail that slows other players is now only left behind when a player uses the blow dryer powerup, and is no longer unique to players without the crown. In addition, we did not have the high-low arena mechanic, because we decided slopes were not worth the additional complexity and debugging.

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.)

Our initial schedule was to have an echo server by Week 2, an MVP by Week 5, and we would freeze our specifications in Week 8. There were a lot of smaller milestones that broke up these large milestones, but these were the most crucial. 

Our final schedule followed the original schedule for the first four weeks. But we fell behind very gradually as the quarter went on. We didn’t have a complete MVP until Week 8 or so when the user interface and the win and lose screens were completed. We theorize that our delay was because we had unforeseen difficulty with the graphics of the game, animation/model loading, particles, slopes, text rendering, and spatial audio. But this is also to be expected, because of the inherent uncertainty in development.

B. 

  1. What software methodology and group mechanics decisions worked out well, and which ones (if any) did not? Why?

We had weekly Trello sprints and bi-weekly team meetings. Each week, our goals were based on our outline in the project specification schedule. We had a “scrum master” but it was very loosely defined as we were all motivated to work. Overall, our methodology worked well, but we think that if we were less motivated then we would have had much less success.

  1. Which aspects of the implementation were more difficult than you expected, and which were easier? Why?

[Andrew] – Using asynchronous network operations in Boost was harder than I expected, because there was a lack of official documentation on how to use the various socket operations in concert (connect, accept, send, receive). Setting up a client-network protocol was easier than I expected, since we were able to leverage the fact that our clients and server had the same operating system to make our data serialization as simple as sending an entire C++ struct over the network. 

[Steven] Getting the floor of the arena implemented was significantly easier than expected. I originally was going to make it an actual object, but I was able to get a better result by just having a few checks for the player’s position being within a certain region. One aspect that was harder than expected was translating what was in the scene into the game logic, as a decent amount of objects needed multiple bounding boxes. 

[Terry] Learning how to get our Audio Engine setup with our library was hard in the beginning, finding the right documentation and just the essentials that we would need to implement. 3d sound was very tedious to implement and debug. 

[Will] Cascaded shadow maps >:( I spent a little over a week on CSM and they just never quite worked. I think the ultimate issue with them had to do with the texture array, I probably wasn’t writing or reading from it correctly. But since it was my first time using it, I am not quite sure. Plus, since it was an array, it was way harder to debug because I couldn’t just display what the buffer held. On the other hand, light attenuation was really easy to implement, and made the graphics noticeably better. 

  1. Which aspects of the project are you particularly proud of? Why?

[Aiden] I am most proud of the map/arena for its topology and the car designs because I felt they represented our aesthetic well.

[Andrew] I am most proud of the overall aesthetic of our game, from the design of the arena, makeup pit stops, and cars to our soundtrack, because they really make the game unique.

[Steven] I am particularly proud of the collision correction and how it was able to handle both horizontal and vertical collisions smoothly. I also like the feeling of movement quite a bit, and I was happy with how efficiently I was able to create the floor of the map.

[Terry] I am proud of how cohesive our game is from menu to gameplay to win screen, and all the art/sound that help to reinforce the gameplay experience. 

[Will] I am really happy with the graphics engine after I added bloom and particles. I am especially proud of how I rendered particles. I first rendered the scene to a buffer where only the were particles colored, (and the rest of the scene was rendered as black). Then I used my gaussian blur shader to blur that buffer, and finally re-combined it with the regular scene. Although we only used cubes, this would let us use any model as the particle, and still get that transparent/ hazy look.

[Evan] I’m very proud of how the game looked in the end and how many features were added and how polished it was by the end of the project. The lighting and start screen help it really look like an actual game I would buy.

  1. What was the most difficult software problem you faced, and how did you overcome it (if you did)?

[Steven] Slopes were probably the most difficult thing I worked on and I eventually decided they weren’t worth the additional debugging. My method was to offset each vertex of the bounding box so they were above the ground, take the cross product of the diagonals to get a new up vector, and then adjust the bounding box again to make sure it was above the ground. What eventually made me give up was realizing that there were places in the client that were hardcoded to use a completely vertical up vector, and implementing slopes would also require changing all of those.

  1. 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?

We only used C++ to develop our game. We would recommend C++ for future groups, especially since you can use OpenGL for the graphics side.

  1. 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.

As a group, we wrote an upper bound of 15,891 lines of c++ code. This was based off of github’s code index, but includes library files. The amount of code we wrote is probably closer to 10,000 lines, as a file-by-file line count revealed that we wrote 12,462 lines of code (including comments and new lines).

  1. In developing the media content for your project, you relied upon a number of tools ranging from the underlying graphics 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? Are there any tools that you used but, looking back, you would avoid?

[Aiden] For all modeling, we used Blender. I highly recommend this tool as it is not only free, it also is very powerful and has an extensive community that is constantly uploading tutorials and posting to forums. 

[Emily] Aiden could export models from Blender as .obj or .fbx files. We exported objects as .obj because there was a very easy to use object loader that we could easily integrate with our existing scene graph implementation, so initially this method made the most sense. I decided to use this object loader since it was a very simple string parser and it detailed very explicitly what settings to use to export models from Blender. However, this eventually was a problem for our team in the future. Unlike .fbx, animations cannot be exported using .obj files. I was eventually able to work around this by writing my own basic animation parser and only using transformation animations. However, it would have been nice if Aiden could do more complex animations in Blender. I believe Assimp, the library that most teams use for model and animation loading, has its own scene graph manager too which would have solved all these issues, but we wanted to use our existing scene graph manager. 

  1. Would you have rather started with a game engine or would you still prefer to work from scratch?

[Aiden] I personally would have preferred to work in an engine such as Unity, as that is my usual workflow and would have allowed me to create a map and create collisions on my own to iterate on the map more as an artist.

[Will] I think that the class better without a game engine, seeing what goes into one was very cool. But if I were to make another game, I would definitely use a game engine. I feel like I would be able to accomplish more, and I think it would be much easier to optimize the performance of the game. That being said, I am glad that I have the experience of making a game from scratch. I feel like I have a much better understanding of what goes into the design of a system than if I had used an engine. I think the class would be worse if we used an engine instead of working from scratch.

[Andrew] I would still start from scratch because I value the learning experience that comes with building the game without an engine. For future game development, however, I would use a game engine just to make development more portable and efficient.

[Steven] For my own projects I would still use a game engine but this class would’ve been significantly less interesting if it used one.  Worrying about the specifics of things like the scene graph and object organization was something that doesn’t really come up when working with an engine and I’m glad I got to experience it.

[Evan] I really appreciate it being from scratch. I feel like one big aspect of the class is that it teaches you about systems and all of the aspects of some application from the graphics to the network. While this class was specifically for a video game, I think it was still very beneficial to learn what it’s like to develop these different pieces from scratch.

  1. 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?

[Andrew] I would still use Boost again if I were starting over. The documentation for using network operations in Boost is difficult to find, but it is out there. Overall, Boost hid the low-level details of sockets that enabled me to set up our client-server connection faster, which made it worthwhile to use. One lesson I learned is to remember that the function handlers for Boost asynchronous network operations are not immediately invoked; this is relevant because it means any data structures that are accessed by the function need to still be in scope when the function is eventually invoked. Practically, this means that the function handler should not be accessing any stack-allocated array, or else very strange bugs will ensue.

[Terry] I would use the FMOD audio library again because of how powerful it is and how relatively simple it is to setup. It supports 3d sound very easily and you don’t have to worry too much about how many sounds are playing at once. One thing that I would advise is to understand the audio goals that the engine you’re building is trying to achieve and be very specific in audio channel management. 

  1. For your group web pages, we used wordpress. Were you satisfied with wordpress, or would you rather have used some other system for maintaining your group web pages? If you had a choice, is there another system would you have preferred to use (or even just doing everything on your own using HTML, CSS, and JavaScript)?

[Aiden] I felt WordPress was very intuitive to use.

[Emily] WordPress was a good enough tool for us to use for our team websites since I don’t have much experience building websites. It was really easy for us to do most of our weekly status reports in a separate Google Doc, and then copying and pasting it into the WordPress site. However, it is inconvenient for us to embed videos into WordPress. I don’t know if this is an issue with other website editing tools, but we got around this by creating gifs and embedding the gifs or by embedding a link to a video hosted on another service.  

[Andrew] I was satisfied with WordPress. Although it took some time for me to initially set up our WordPress site using the instructions provided by Cindy, once the site was set up, it was fairly easy to edit. Embedding videos did not work easily; we had to change our server permissions in order to upload videos, and this was not immediately apparent.

[Terry] I thought that WordPress was a bit overkill in terms of the functionality that it provided and what we actually used. We very much just wrote all of our information on a Google Doc and then copied the text over to the site. I would prefer something easier to use like Google Sites as this would have better support for embedding videos as this was difficult on WordPress due to space constraints. 

  1. This is the second year we’ve used a discord server for the class. Would you recommend that we continue using discord in the future?

[Aiden] I would recommend continuing to use Discord, but encouraging use of the same server by the different groups. Our personal server worked very well for us, and would like to see that kind of community shared across the whole class.

[Andrew] I recommend using the class Discord in the future, because it is more convenient to use than Piazza. Although I did not really use the class Discord throughout the quarter, I was able to use it at the start of the quarter to debug an issue with our WordPress site.

[Emily] I noticed that the class Discord wasn’t used that much, probably because we had our own team Discord server where we could create and modify our own channels. I don’t DISLIKE the class Discord server, but I felt like it could have been used more. It is still nice to have though, so I would say we should still have a class Discord server in the future.  

[Steven] I liked the class Discord but never used it. I do think it would be a cool way to get more interaction between groups if used properly.

[Terry] I think that the discord server for the class was nice but it had the same goal as the class Piazza. I feel like we could’ve just used one or the other and we would’ve been able to use the platform more. We created a discord server for our own team and that’s where I interacted more of the time. 

[Evan] Discord was nice but I don’t think it’s necessary. It may help give some people feel more comfortable asking for help, but for me personally, I never used it or felt any need to use it. I like that announcements were still on Piazza, and I generally like Piazza more for more important class announcements/logistics, and Discord would be more for quick help. As some of the other people said, it wasn’t used very much so it’s a little hard to know how useful it can be.

  1. 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?

[Aiden] I really learned the value in spending time with the team and actively trying to get to know everyone. I believe that our synergy as a whole was very high in the final weeks of the course because of this. I felt much more productive with this team than my design project team in another course since I rarely had these interactions with them.

[Andrew] I learned that it’s really crucial to establish a rapport with everyone in the team. Being friends with everyone in our team helped us collaborate more effectively.

[Steven] I learned a lot about using GitHub, which I did not know much about coming in (I had never used branches before). I also learned that having a group and being able to share my progress is a great motivator.

[Will] I think this project showed me how much more effective groups can be when everyone trusts each other. I got to know everyone on the team much better than in any of my previous groups, and it was clear that everyone was very motivated to work on this project (as opposed to something like 110, where people just kind of do the minimum work needed and never interact with their team). Because we were all friends, I was never worried to talk about things I messed up (like accidentally pushing to main), and because everyone was super motivated, I was never worried about people not doing their work.

  1. Looking back over the past 10 weeks, is there anything you would do differently, and what would you do again in the same situation?

[Andrew] I would redo our network protocol implementation. The drawback of using our struct method, is that we had to recompile our code every time we changed the number of players in the game, which made debugging slower and made our game less scalable to a larger number of players. I would have taken more time to implement a protocol that could support an arbitrary-sized network packet.

[Terry] I would also redo the server implementation of our code to be able to be able to support multiple “lobbies” so that we wouldn’t need to restart the server every single time just to make an update to the client. This would also allow us to be able to serve more players eventually down the line as well (even if outside the scope of this class). 

[Steven] My basic game logic structure is to have a manager that keeps track of all objects by putting them in a vector.  Each object gets an id that is its index into the vector of all objects.  This way, an object can gain access to the information of other objects simply by having its id.  This setup worked very well and I would definitely use it again.  I think my biggest mistake was making the server’s and client’s representation of the world too different.  For the client, everything is a collection of nodes in a scene graph.  These nodes store matrices that are used to transform the models associated with them.  For the server, everything is a collection of objects tracked by the manager.  These objects have a vector for position, another for direction, and a bounding box that is generated based on a length, width, and height that must be specified manually for each object.  The number and types of objects don’t always line up with the scene graph’s nodes (makeup booths, for example, are three walls and a “makeup” object to handle keeping a player in the booth and toggling the solidity of the bar blocking the exit of the booth) and the information exchanged between the server and client is sparse at best.  This means that adding anything to the game requires modifying the scene graph and the manager’s object list independently, which is nontrivial due to the difference in formatting.

[Will] I would implement particles slightly differently. The current system renders each particle model with a unique draw call. I learned too late that OpenGL has something called instancing, which would allow me to draw a large number of particles with a single draw call, which would vastly improve performance. I couldn’t add more particle effects, like for makeup booths, or when cars crashed into things because of performance issues. But had I used instancing, I believe I would have been able to.
We also had a lot tech debt (I guess is what I would call it) that accumulated throughout the quarter. Client’s main.cpp was well over 1000 lines, and in retrospect, we should have had different classes for handling input, network, and rendering. Scene.inl was another 1000 line file, where we initialized the scene graph for the whole game. I don’t know exactly how we could have restructured it, perhaps with a json file or something, but the file was quite long. Finally, near the end of the quarter, I (and perhaps others) were guilty of adding random side effects to functions. Until I had to scrap it for performance, I was using the audio and animation players to also make particles, because we didn’t have a dedicated event handler.
Finally, I would also have handled the camera slightly differently. Near the end of development, we added trampolines, which were a very good feature, but the ability to bounce caused the camera to clip through walls way more than it did before. I think implementing collisions for the camera would have been the most practical way to solve it, but unfortunately we were too late in development to really do that.

[Evan] I feel that I could have contributed more to Steven’s Game Logic. I think in general, it was difficult to join other people’s teams because you need to spend time understanding each other’s code, and it seemed like it would be faster for other people to work on a specific feature instead.
I also wish our code was a little bit more organized because it felt like things were all over the place by the end. I know that it was difficult because it was our last priority, but it would have been nice and easier to add onto in the future.

  1. Which courses at UCSD do you think best prepared you for CSE 125?

[Andrew] CSE 124 and CSE 167 were the courses that best prepared me for CSE 125. CSE 124 made me aware of client-server protocols, which was relevant for the network portion of CSE 125. CSE 167 made me aware of scene graphs and shaders, which helped me understand the graphics parts of our project better and allowed me to contribute. However, I think being motivated was the most important factor in helping me do well in CSE 125.

[Steven] CSE 167 and CSE 169 were the courses that prepared me the best.  In 167, the scene graph project applied pretty directly to this course, while the cloth simulation project in 169 was a good introduction to moving complex objects in a 3D environment.  That said, the experience I gained from game jams and my own projects was definitely the most helpful when working on game logic.

[Terry] While not directly, I think that CSE 110 best prepared me for the dynamics of CSE 125, working in a large software development team, and implementing our own ideas into a deliverable software engineering project. It helped me transition from the mindset of completing a PA, to tasking our high level and iterative goals to achieve our project specifications. Other than that, I think I just synthesized ideas from a bunch of different courses/past experiences. 

[Will] Echoing what others have said, CSE 167 and 169 were incredibly helpful for making the graphics engine. I don’t think it would be possible to work on graphics without at least taking 167 (or having outside experience). I also found CSE 160 very helpful for thinking about how shaders work. Having an understanding of GPU programming was most obviously helpful for making the gaussian blur shader, but I am sure that that knowledge made working on other shaders much easier.

[Evan] Network courses like CSE 123/124 were important for working on the network. I wish I took CSE 167 to be better help on the Graphics end. Also knowing C++ is important if you use it, and ECE 17 course was very helpful for that.

  1. What were the most valuable things that you learned in the class?

[Aiden] As a game developer, I learned a lot about what I once took for granted in engines such as Unity and the amount of work that goes into making a game look good. Seeing a game being built from scratch helped me reframe the number of possibilities made available from using an engine.

[Andrew] I learned that game development is quite complex and requires a breadth of knowledge in physics, graphics, art design, sound design, and networking.

[Will] This class showed me that I can take on and complete huge projects. It was very cool to take what I had learned at UCSD and actually apply it so something of this scale.

  1. Please post four final screenshots of your game on your group pages for posterity. I will display them on the group web page.

C. 

  1. What advice/tips/suggestions would you give students who will take the course next year?

[Andrew]  Make sure you have a release mode version of your game that is optimized for better performance, and use this for faster debugging and the final demo.

[Will] learnopengl.com is extremely helpful if you are working on graphics. I also highly recommend implementing bloom, it was the single biggest improvement I made to the graphics engine, and make the game look significantly better.

  1. How can the course be improved for next year?

[Aiden] Add more spots for artists and musicians! Get more people in this class!!!

  1. Any other comments or feedback?

Thank you for an awesome quarter!

This is my favorite class I took in my 4 years at UCSD!