Civilization 0.5 Class Project, Design and Implementation Java, JavaFX

All Projects

CSC 335 is the University of Arizona's object-oriented programming course, where many students are exposed to the exciting world of OO for the first time through the lens of Java. It's also the first course in the standard track that puts a big emphasis is on getting people used to working with a group: UML, git, how planning phases and division of work works, and so on.

This final project was the culmination of that, where groups picked whatever they wanted to do for their own projects (assuming sufficient complexity), designed them, divided the work, and coordinated implementation across a team. The rest of my group was comprised of students of expected college age, and I was the "old guy" who had been working for a while, so leadership responsibilities tended to land on me. I didn't mind.

Design

The idea for a Civ-style game came from Luke, one of the group members, and it was an immediate hit with everyone else. We knew we wanted the essentials: AI opponents and local multiplayer, resource management, units and simple battles, varied terrain. From there it was off to the planning phases, where we mapped out all the various components we needed, did the necessary flowcharting, and generated the proposed UML class diagram that was our first deliverable.

A collection of tiles I created for the game's isometric grid
A collection of tile artwork used in the game. Terrain is a combination of free-to-use texture assets and drawn features. The five tiles in the upper left are overlay squares, for e.g. indicating a unit's possible movement options or placing underneath the mouse cursor to highlight its position.

Given my prior background in UI work and the way I was able to adapt to JavaFX's idiosyncracies (Connie, another group member, called the way I meshed with it "weird" and "unnatural"), I was elected to helm the interface and rendering efforts. While keeping the game grid-based was in our simplifying assumptions from the start, I thought it might be more visually interesting to make it isometric. Once I settled on a final camera angle (the degree of isometric perspective "squishing" effect), it was a simple matter to take the existing grid data and map it to a new, rotated visual grid. One quick function to translate screen coordinates to grid coordinates (and vice-versa) later, and we were in business.

A collection of various sprites used in the game, including a city tile and a horse sprite in various states
A collection of initial sprite work. From left to right: settlement mocked up in Figma, simple placeholder sprites while figuring out what our units were going to be, and resource artwork meant for various states and placements.
My first mockup of the game's UI, showing panes for unit properties, city properties, player readouts, and an 'end turn' button

I mocked up a simple UI in Figma with a fast turnaround, and while it's minimalist and a little rushed, I think it turned out to be usable and relatively organized. I didn't know much about JavaFX's typesetting and effects abilities, besides, so "simple" was the name of the game. I included a few nice-to-haves in the mockups, such as the combat and movement modifiers we had mentioned in passing while discussing, and their inclusion made the others more motivated to implement them.

Sprites were a combination of artwork found by Luke (he assured me that it was okay to use) and some simple Figma shapes; for example, the castle sprite we used for settlements was simply a few vector shapes with gradient fills. I had entertained the idea of doing some renders in Blender, but Figma was faster and met the bar of Good Enough for a Class Project. At this point, most other sprites were placeholder rectangles of various colors that we'd replace while we worked, as the unit types we wanted were still in flux.

Implementation

The UI/rendering pipeline turned out to be simple, even when using JavaFX, a framework designed for more standard windowed applications. I ended up with a series of layers that could be individually re-rendered when needed: background and terrain tiles sat static at the bottom, followed by layers for range indicator tiles, fixed sprites (e.g. settlements), movable sprites associated displays such as health bars, fog of war, hover/position indicators, and UI panes. JavaFX includes data binding, the ability to link data updates to targeted UI rerendering a la React, and I used these capabilities for the UI layer. For other layers it was faster and easier to write my own simple rerendering methods, which were more brute-force but lighter and less prone to error.

A collection of fog of war tiles in various permutations of connecting (smooth) vs non-connecting (wavy fog texture) edges

Along the way I also volunteered to add fog of war, introduce settlement building, and take over the unit battling mechanics, since all of them sounded like fun things to try and I was making good pace.

I tackled fog of war first, since it seemed the most interesting to implement. For the art itself I went with a somewhat simplistic approach where I baked out assets for each possible shape of a fog of war tile, but given more time I probably would have tried to find a way to do this programmatically. The other "stretch goal" items turned out not to be as tricky as I first feared, and by the end I felt as though our game kept to a high standard relative to the assignment.

A set of screens showing varying gameplay and active UI screens

Making a game was certainly one of the most enjoyable projects I remember from school. Working in a group was pleasant and easy (I perhaps had a head start because of my ongoing job experience), and it was fun to guide people through using git and dividing responsibilities. While the final product was nothing groundbreaking, I felt like we had made a solid game: we defined our functionality well, we tested a lot, and I feel like the code I wrote was well-documented and maintainable. Thanks for the fun experience, CSC 335.