Hey, everyone. Over the past few months, I've been working very hard on a particular project and have finally reached a critical milestone. Today I'm proud to announce I'm releasing the first in a series of stories titled "A Study in Human Traditions" on January 8th.
"A Study in Human Traditions" is a series of interactive short stories following Simon, a scientist who needs your help to understand the stranger parts of human culture. Help him decipher such ancient rituals as "Dinner Party", "First Date", and "Democracy", and perhaps learn something about yourself in the process.
I'm releasing Entry 1: "Hollowed Weed" on January 8th, with more entries to come in the following months. Mark your calendars or other alternative time-tracking devices!
BeauPrime's Nook
Game development and other tidbits.
December 27, 2015
April 30, 2015
Rigid Body Simulation (Game Physics)
For this Game Physics project I tried my hand at a rigid body simulation, which for now remains incomplete. Due to a combination of factors the simulation doesn't work as nice as I'd like - some of the math is a little fuzzy and collision resolution between bodies is jittery.
A good portion of the difficulty came from understanding the underlying matrix transformations and quaternion mathematics, which even now I'm still trying to figure out, at least from a math theory standpoint. This contributed to the challenge of resolving collisions properly, as the process involves many matrix transposes and transformations, as well as some inversions.
I'm not too happy with the results of this project, so I'm going to attempt to fix these up within the next few days, hopefully with a slightly better understanding of the resolution process this time.
April 29, 2015
Component-based UI System (Project Postmortem)
An important project I struck out on this semester was the creation of a component-based UI system portable to other platforms. I wanted to create something that scaled nicely and allowed artists to create beautiful layouts without having to write a line of code. This worked out very well and has become one of the standout systems in my framework.
There were several important points I wanted to hit on with my UI system. I wanted the system to be flexible enough to be portable to any other backend. That is, I wanted something that didn't rely on platform-specific code to work. While obviously the actual rendering is handled on a per-platform basis, the API had to abstract this out. Additionally, I wanted to achieve some level of resolution-independence, particularly for mobile platforms. Positions needed to be specified such that things could be anchored to the sides of the screen without writing code manually positioning it relative to screen size. All this was intended to decrease the amount of time I spent re-implementing common structures across UI forms and create something that made it easier for designers and artists to create content without an engineer.
My objectives, for the most part, were met. I created a coordinate system composed of two parts - screen-relative and pixel offset - that allowed things to be positioned and sized uniformly across multiple devices and screen resolutions. Retrieving the absolute position on the screen is as easy as multiplying the screen position by the UI size and adding on the pixel offset. This made, for example, corners much easier to deal with.
I implemented a UI stack system which allowed forms to animate in a generic manner as well block touches to lower forms, which made the creation of message boxes much simpler. Forms are depth-sorted, and elements from top forms can block touches to lower forms, allowing touchable elements to occlude deeper elements and prevent unwanted touches. The animation system gives a generic way of making opening and closing animations for forms, allowing elements to slide, scale, and fade in a customizable manner. This added a nice layer of polish to the game, particularly when we added easing functions.
Additionally, I created several common controls, including buttons, checkboxes, and radio buttons. Finally, I implemented a slick tweening system, which allows each individual element to be rotated, positioned, scaled, rotated, faded, and color-shifted at will with very little code. This is built on top of one of my existing value tweening systems and required a bit more work to implement without using expensive lambdas, considering that tweens of certain types were not allowed to overlap - I couldn't, for example, have two position tweens running on the same element without unwanted behavior. Finishing this system added a nice layer of polish, giving us flashing UI elements, arrows that scale, buttons that pop up, and selection icons that shift around the map instead of teleporting. The visual benefits of this system are immediately obvious and well worth the effort to implement.
After finishing this project, I've concluded that having a dedicated UI system helps cut down on redundant development time. I created a system early on that made creating forms a five-minute process instead of a thirty-minute process, and while creating the system took time, the effort was worth it. It also gave my Production game much more visual polish. Another important lesson was that building this system does not necessarily mean that artists and designers will actively work with it. I did not spend enough time introducing it to the people it was intended for, which led to me spending more time than I would like on the layouts instead of dedicated UI people.
There were several important points I wanted to hit on with my UI system. I wanted the system to be flexible enough to be portable to any other backend. That is, I wanted something that didn't rely on platform-specific code to work. While obviously the actual rendering is handled on a per-platform basis, the API had to abstract this out. Additionally, I wanted to achieve some level of resolution-independence, particularly for mobile platforms. Positions needed to be specified such that things could be anchored to the sides of the screen without writing code manually positioning it relative to screen size. All this was intended to decrease the amount of time I spent re-implementing common structures across UI forms and create something that made it easier for designers and artists to create content without an engineer.
My objectives, for the most part, were met. I created a coordinate system composed of two parts - screen-relative and pixel offset - that allowed things to be positioned and sized uniformly across multiple devices and screen resolutions. Retrieving the absolute position on the screen is as easy as multiplying the screen position by the UI size and adding on the pixel offset. This made, for example, corners much easier to deal with.
I implemented a UI stack system which allowed forms to animate in a generic manner as well block touches to lower forms, which made the creation of message boxes much simpler. Forms are depth-sorted, and elements from top forms can block touches to lower forms, allowing touchable elements to occlude deeper elements and prevent unwanted touches. The animation system gives a generic way of making opening and closing animations for forms, allowing elements to slide, scale, and fade in a customizable manner. This added a nice layer of polish to the game, particularly when we added easing functions.
Additionally, I created several common controls, including buttons, checkboxes, and radio buttons. Finally, I implemented a slick tweening system, which allows each individual element to be rotated, positioned, scaled, rotated, faded, and color-shifted at will with very little code. This is built on top of one of my existing value tweening systems and required a bit more work to implement without using expensive lambdas, considering that tweens of certain types were not allowed to overlap - I couldn't, for example, have two position tweens running on the same element without unwanted behavior. Finishing this system added a nice layer of polish, giving us flashing UI elements, arrows that scale, buttons that pop up, and selection icons that shift around the map instead of teleporting. The visual benefits of this system are immediately obvious and well worth the effort to implement.
After finishing this project, I've concluded that having a dedicated UI system helps cut down on redundant development time. I created a system early on that made creating forms a five-minute process instead of a thirty-minute process, and while creating the system took time, the effort was worth it. It also gave my Production game much more visual polish. Another important lesson was that building this system does not necessarily mean that artists and designers will actively work with it. I did not spend enough time introducing it to the people it was intended for, which led to me spending more time than I would like on the layouts instead of dedicated UI people.
Scripting Languages, Bytecode, and Feature Creep (Project Postmortem)
At the beginning of this semester I embarked on a small project to create a ZZT-OOP style language for my Console Programming class. For several reasons, this did not work as intended, but the experience was still worthwhile.
My original objective was to create a simple scripting language, complete with syntax, parser, and runtime, to enable designers to more easily script behavior. I was inspired by ZZT-OOP, a language included with the influential 90's ZZT game and world editor.
This goal got away from me as I delved further into language design. I started out trying to define the syntax, but found that it was easier to write the bytecode instructions first. Each instruction contains two parts - an opcode and an optional argument. A program is just an ordered list of these instructions (with optional labels) combined with a program stack, a data stack, and a context stack, to maintain which variable table is being referenced. Most opcodes operate on the data stack, pushing or popping values. Others push data from the variable table onto the data stack or push the top value from the data stack into a spot in the variable table. Still others branch or jump to various labels within the program, allowing for the creation of loops and conditionals.
This created a really cool demo, but led to the creation of something that would require more work to interpret compared to the single-instruction, command-line style of ZZT-OOP. I began looking more closely into Lua, borrowing its "table" concept for variables. Unfortunately, this led to an attempt at parsing Lua-style syntax, which, if you've ever compared ZZT-OOP to Lua, it's night and day. Lua, in comparison, is significantly more flexible, which makes parsing it much more of a challenge. These difficulties served to slow my progress, and with the constant need for progress in my Production course, my work ground to a halt.
Luckily, this attempt was not for naught. I definitely understand more about how languages work behind the scenes and understand the bytecode pattern much more completely. I also learned a lot about the limitations of C# in creating a scripting language. Most other implementations are in C or C++, which allow for unions and treating strings as char pointers. Comparatively, C# requires that you hack unions with FieldOffset, and strings are treated as managed copy-on-write objects, making it impossible to embed them within a C# struct "union". I also received another lesson in scope management, and should probably not get distracted by shiny popular languages in the future if I return to this endeavor.
So, the most important takeaways from this project: bytecode is pretty easy, language specifications are more difficult, and translating between the two is tricky. Also, designers don't really enjoy writing code, so a visual scripting tool is not only easier to use, but easier to interpret into bytecode. If I return to this, I'll likely make some kind of WinForms tool instead of a full-blown written and parsed language. It's a bit more effort from a tools perspective, but if my goal really is to empower designers, then this is a much better alternative.
My original objective was to create a simple scripting language, complete with syntax, parser, and runtime, to enable designers to more easily script behavior. I was inspired by ZZT-OOP, a language included with the influential 90's ZZT game and world editor.
This goal got away from me as I delved further into language design. I started out trying to define the syntax, but found that it was easier to write the bytecode instructions first. Each instruction contains two parts - an opcode and an optional argument. A program is just an ordered list of these instructions (with optional labels) combined with a program stack, a data stack, and a context stack, to maintain which variable table is being referenced. Most opcodes operate on the data stack, pushing or popping values. Others push data from the variable table onto the data stack or push the top value from the data stack into a spot in the variable table. Still others branch or jump to various labels within the program, allowing for the creation of loops and conditionals.
This created a really cool demo, but led to the creation of something that would require more work to interpret compared to the single-instruction, command-line style of ZZT-OOP. I began looking more closely into Lua, borrowing its "table" concept for variables. Unfortunately, this led to an attempt at parsing Lua-style syntax, which, if you've ever compared ZZT-OOP to Lua, it's night and day. Lua, in comparison, is significantly more flexible, which makes parsing it much more of a challenge. These difficulties served to slow my progress, and with the constant need for progress in my Production course, my work ground to a halt.
Luckily, this attempt was not for naught. I definitely understand more about how languages work behind the scenes and understand the bytecode pattern much more completely. I also learned a lot about the limitations of C# in creating a scripting language. Most other implementations are in C or C++, which allow for unions and treating strings as char pointers. Comparatively, C# requires that you hack unions with FieldOffset, and strings are treated as managed copy-on-write objects, making it impossible to embed them within a C# struct "union". I also received another lesson in scope management, and should probably not get distracted by shiny popular languages in the future if I return to this endeavor.
So, the most important takeaways from this project: bytecode is pretty easy, language specifications are more difficult, and translating between the two is tricky. Also, designers don't really enjoy writing code, so a visual scripting tool is not only easier to use, but easier to interpret into bytecode. If I return to this, I'll likely make some kind of WinForms tool instead of a full-blown written and parsed language. It's a bit more effort from a tools perspective, but if my goal really is to empower designers, then this is a much better alternative.
April 3, 2015
Mass Aggregate Physis (Game Physics)
For this Game Physics project I confronted a mass aggregate-style physics simulation, attempting to get basic shapes and motion from rod and cable constraints. For various reasons this didn't turn out as expected.
Debugging mass aggregate systems can be time-consuming and challenging, particularly when the issues only show up at scale. One physics rod may correctly resolve two linked particles, but what if there are four inter-dependent rods connecting a pyramid? I pored over my contact resolution algorithm many different times, spotting no differences between my code and the provided code, yet something was clearly wrong. Shapes would collapse upon themselves or, worse, explode outward. Eventually, I managed to resolve the issues, though more through brute force than anything else. Given more time, I would like to figure out exactly where my original simulation went wrong.
The project also took longer than it should to complete. I underestimated how long debugging the simulation could take. After all, the algorithms are pretty simple and laid out for us in the course material - I only have to implement them, quickly test them, and get the gameplay working. Easy, right? This didn't hold true, and I spend too much time at the end attempting to fix basic physics issues. The physics work, but performance could be improved. Additionally, this cut time from being able to improve the presentation of the simulation by, say, rendering lines for each physics rod in the scene.
February 17, 2015
Planetary Simulation (Game Physics)
Over the past few weeks, I've created a planetary physics simulation for my Game Physics course. It uses OpenGL, GLUT, and GLUI to render out the simulation.
I've built a classic implementation of an Entity-Component system, where Entities only serve to bind data Components together, though my Entity also contains a position, since that is shared most often among components. The Systems operate on the Entities with certain Components. Thus, I have a PhysicsSystem which operates on all Entities with a PhysicsComponent. This allowed me to update the simulation all at once, instead of at a per-object basis, which could lead to some issues with state synchronization.
There were some challenges with the sheer scale of the numbers involved. In kilometers or kilograms, the distances or masses might be too large to operate on properly. I converted everything to astronomical units and solar masses, though this also caused some problems with very small numbers. In the end, though, I was able to get the simulation working mostly correctly. The Earth's moon is still a little weird, as I was not able to find the correct numbers to get it to work properly.
Getting the rendering to work also had a few challenges, most notably in rendering the planets with different textures. While I took a Graphics II course back in Montreal, that was in DirectX, and we had been given a solid framework to build off of. Here, I started from nothing to get an OpenGL renderer - not necessarily too challenging, but time-consuming.
Subscribe to:
Posts (Atom)