Tabletop Dragon Age – “We Threw The Box” [Sessions 1-2]

A few notes before I begin recapping the insanity I’ve recently been a part of:

First, I’m not super familiar with Dragon Age lore since I’ve only played the first game and I don’t remember many of the details involved. This lead to quite a few moments of spectacular stupidity.

Second, I’m also by no means an RPG veteran. I’ve played a handful of tabletop games in the past, but most of them never really took off. Not to mention the Dragon Age Tabletop RPG is by far the most “normal” set of mechanics I’ve used so far. Most of the ones I’ve played have been percentile systems or weird d100 systems like Anima. (None of them were bad, just really weird and complicated as opposed to this one which is much more straightforward.)

Finally, the character I’m playing is a direct reference to a character that a let’s play series I really like came up with and typically plays as whenever they’re in a Bioware or Obsidian RPG. Said character’s favorite way of killing people is by exploding their pants. He’s a huge kleptomaniac, a drunk, a troll, and can generally be described with the phrase “chaotic stupid”. (Some notable examples include stuffing grenades down a DJ’s pants and nuking some irritating children in Fallout 3.)

When I originally played Dragon Age: Origins, I attempted to play as this character, but couldn’t bring myself to be that big of an asshole.

Okay, with that out of the way, let’s see if I can accurately describe how a simple heist lead to unleashing an ancient evil on the world and burning a major city to the ground.

Our story began actually long before I (or my character) arrived, as it turned out I was joining an already active campaign that two people had to drop out of. The summary I got of their past adventures was that they “just did the pre-made campaign”, but ended up making a giant corpse pile, setting it on fire, and leaving a burning village to their fate. Awesome. Already a respectable bunch of people I’m joining.

The two remaining characters were a dwarven warrior named Idrax, and a human apostate mage named Celene.

After fleeing the country and leaving a trail of death and destruction behind them, our two…I guess I can’t really call them “heroes”, so let’s just say “protagonists”…find themselves in Ostwick. Celene is looking for the circle that has her phylactery and has been given some information from a drug addict that it’s here in the Ostwick Circle. So all she and Idrax need to do is break in, destroy it, and leave. Maybe not simple, but at least straightforward.

This is where my character comes in. Reginald Cuftbert (a human rogue) was an Orlesian noble. He was rather disliked by his family since he was such an asshole, so they attempted to have him arrested for a crime he didn’t commit. Deciding that if he were going to be arrested it should be for something he actually did, he finds out about this plot, steals everything that wasn’t nailed down, and fled the country. (His family wasn’t wrong – he is an asshole.)

Reginald found himself in a bar in Ostwick, drinking heavily and trying to decide what to do next when Celene and Idrax walk in. He overhears their conversation about breaking into the Circle and decided that it might be good to join in on this since, you know, while they’re busy with whatever they’re doing, he can make some serious bank robbing the place.

Much of the rest of the first session was spent planning our heist, or at least preparing for it to the best of our abilities. I mean, we were pretty badass, but the place is crawling with templars and mages, neither of which we wanted to tussle with. So we each split up and decided to do our own thing – Celene used her contacts to get a map of the place, Reginald sold off some stolen family heirlooms to buy some Fereldan templar armor and Fereldan circle mage robes to use as disguises, and Idrax got a crate of lyrium (only somewhat tainted) from the dwarven mafia, who, in return for their help, we promised to kill someone for them. They asked us to murder the Knight Commander, leaving their own plant, the Knight Captain, in charge.

I also bought a lockpick, thinking it’d come in handy (spoiler: it does).

This latest session of actually infiltrating the place, though…oh man…it started off like an Abbot and Costello sketch and just went downhill from there. Somehow, we were so incompetent, that our incompetence rolled right around to brilliance and ended up getting us out of tough situations.

So we start by recapping what happened, what our goals were, and a rough outline of what we planned to do. We decide to use the back entrance, which is normally reserved for shipments and such, and bring the crate of lyrium with us. Unfortunately, I had the highest communications out of those who were actually allowed to speak, and I had no fucking clue what to do. We had to retcon slightly after I said something so unbelievably stupid that there was no way my character wasn’t at least kind of prepped for this. Our story ended up being that we were transferring a mage from one Circle to this one, and “you should’ve gotten a letter about this several weeks ago.” Ultimately, Fredrick, the nice templar running the loading bay, let us in and directed us towards the first enchanter to drop off the new mage.

It should be noted that Reginald is Orlesian (so they think he’s a pompous fool), Celene is Fereldan (so they think she’s akin to a rabid dog), and Idrax is a dwarf (so him being a templar is incredibly unlikely). So even if they didn’t know we came here to rob them, pretty much nobody would think very highly of us.

This was already as suspicious as things could get, but we managed to make it into the building. From there, we knew our destination was downstairs, but realized pretty quickly that we had no real idea where exactly the vault was. And since we were explicitly told to head upstairs…we just decided to wander downstairs and check the place out. Fortunately, we managed to do this without being seen.

The Circle tower had three basement floors, all connected with a spiral staircase. We make a quick stop on each floor and see three nearly identical layouts – a hallway that circles around the perimeter of the tower and some kind of door near the staircase landing. The differences being:

  • The first basement floor had a large, wooden door
  • The second basement floor had a very sturdy steel door
  • The third basement floor had a pile of rubble

We knew that one of these was the vault, one of these was the dungeon, and one of these was a harrowing chamber. (As it was described to me: a room where demons and dangerous mages were often ‘dealt with’.) Having reached the bottom floor and finding a pile of rubble, we all decided that this must’ve been the harrowing chamber and it just collapsed at some point. Apparently they’re supposed to be designed to do that in case what’s in there is too tough to destroy so it seemed like a reasonable assumption. The second chamber with the sturdy door must be the vault! Going back up, Reginald gleefully picks the lock, pulls open the heavy door, and finds another curving hallway. We hear about four distinct voices from the other side of this hallway and decide to turn back since “we’re not supposed to be here anyway, let’s not get caught”

We finally go back to the first door, the large wooden one. Reginald goes to pick the lock again, rolls incredibly well…

GM: “As you go to pick the lock, you discover that the door is already unlocked.”

Oh.

We all step inside and see a musty old room that looked like it hadn’t been used in ages. Upon seeing many, many bloodstains everywhere, Celene informs us that, no, THIS is the harrowing room, and we should get the hell out of it now.

So…wait…where was the vault? We then all collectively facepalm as we go back down to the bottom floor and discover that the pile of rubble was just an illusion disguising the door. Our GM makes note of the fact that the security system the templars put in place worked pretty well on us, but to be fair we’re all idiots.

Once the illusion was dispelled, we find another door with no discernable lock, but instead had a cup with a spike in it for a handle. We concluded that we needed lyrium-infused blood to make this door open. So obviously our first choice should be to kill those templars we overheard in that locked room. Sneaking our way back up to the B2 floor, we split up, make a plan of attack…only to discover the voices were just four prisoners and not templars. Fuck. Unfortunately, their blood won’t do the trick so we’re back to square one.

In any case, Celene insists we break them out (Well, three of them. We left one behind, something about him being a ‘malificar’ or something), and one of the prisoners informs us that there’s an escape route through a secret tunnel in the harrowing room above. It was also brought to our attention that the person we were asked to murder is actually a nice woman, and the one we were supposed to leave in charge is a murderous asshole. Great.

This prisoner also could’ve informed us of quite a few other things, but most of the info he had we’d already discovered through trial-and-error. The GM just shook his head sadly as the many pages of exposition he’d written were just gone and wasted now.

At this point, we knew needed templar blood to get into the vault. And we’d been explicitly told to go somewhere by Fredrick to go somewhere about, oh, two hours ago. So thinking we could kill three birds with one stone (alleviating suspicions about our intentions and killing the Knight Commander and getting the blood we needed), we decide…to go back upstairs and actually meet with the first enchanter. (Spoiler alert – this was a really stupid decision)

Said first enchanter, Elenora, was…irritated by our incompetence, but we were gone for so long and the fact that we actually came back pretty much said we were just a trio of idiots and not secretly thieves. However, we now had to become separated as Celene was escorted to the mages’ quarters and Reginald and Idrax were asked to go report to the Captain. Celene has her little adventure and makes it to the mages’ quarters with no trouble, ultimately slipping out when no one is looking.

Idrax and I, though…we decide “well, we don’t really want to stray too far from the healer, and the Captain sounds like an asshole who will murder us for no reason”. So through a very lucky “cunning” roll, we ultimately decide to try and blend in. We wander off not too far from the room we just exited we did the most templar thing we could think of – find a door, stand on either side of it, and look angry. After a while, Fredrick wanders by and informs us that the door we’ve been standing guard on is actually just a broom closet, but thinks that this was some cruel prank the Captain pulled on us so doesn’t tell anyone where we are. Turns out our incompetence saved our asses, since, again, we didn’t look like we were suspicious as much as we were just hopelessly lost and very stupid.

Eventually we all meet back up and, though some hints from the GM, realize that we are the biggest fucking morons. We needed blood that was infused with lyrium (i.e. templar blood). On our way back up the stairs, we literally walked right by a LARGE EMPTY ROOM FILLED WITH TEMPLAR BLOOD – the harrowing room and its blood spattered walls and ceiling. After feeling very stupid, we wander back downstairs, gather some of the dried blood, and drop it with some water into the cup on the vault door. It glows and swings open.

Inside the vault were a few things:

  • A large pile of gold
  • A stack of steel boxes which have been chained closed and have big, heavy padlocks on them
  • LOTS of enchanted weapons
  • A pile of skulls with gemstones in the eye sockets
  • A door with no handle or keyhole

The door obviously lead to the closet where all the phylacteries are kept and could only be opened with magic, so Celene got to work opening it. Idrax used his military knowledge to look through the weapons and find some good ones for the party that hopefully weren’t cursed. Reginald just started bagging the gold, but since that didn’t take very long, he also went and opened one of the large steel boxes.

Inside was a qunari skull that had intricate symbols carved in it. I had Reginald call over to Celene “Hey, uh…why do these guys have a big skull in a box?” to which came the response of “…what?”

I was also informed that the skull was giving off a faint humming noise, so Reginald NOPED as hard as he could and shut the box. But, it seemed valuable, so I decided I’m taking this box with me. Because shut up, that’s why!

Celene finally opens the door (though fails to notice the silent alarm that we triggered by doing this) and finds her glowing phylactery. She initially just wanted to smash her own, but I convinced her “Why not just smash all of them? I mean, you hate the circle and want the mages to be able to escape, right?” So one quick Mind Blast and the vault was now covered with glass shards and blood.

Awesome! Rob the vault? Check. Smash the phylactery? Check. Now we just needed to kill the Commander. But since the Knight Commander is supposedly really nice and the Knight Captain is an asshole, we figure we can just skip that part and deal with the dwarven mafia later. I mean, at this point, what’s one more organization out to kill us? The mafia can get in line with everyone else.

It is at this point we all hear footsteps coming from upstairs. It sounds like at least a dozen heavily armored templars are heading down to see what’s going on. We initially prepare for combat, equipping all our fancy new gear, but ultimately decide against it and just hide behind the pile of boxes.

The Knight Captain, Dana (or perhaps her double) storms in, sees the open phylactery closet door and all the blood, starts very loudly cursing and ordering people around. Since we released some prisoners earlier, she assumed it was the work of those prisoners. She ordered that all exits be sealed until this gets sorted out, leaving two templars to guard the vault. I mean, nobody would be stupid enough to just stick around in the vault after doing something like this, right?

After a brief combat with the two templar guards, we sneak our way back up to the harrowing room, since we know that there is an escape route that no one really knows about in that room. Reginald, again, has brought the qunari skull box with him, and I’ve now vocalized my intentions of throwing it at anyone who gets in our way.

Thinking we were home free, we approach the open door to the harrowing room only to find it’s now occupied by five templars. Celene literally tries the “They went that way!” approach, but ultimately fails her roll by one point. The templars realize that they didn’t send any mages down here and have decided that we aren’t who we say we are.

After a panicked, out of game discussion while the GM was rolling dice for initiative, I proclaim “I throw the box in the room at the templars!!”

At this point, the GM let out a heavy sigh, and had to make a decision about what the hell he was gonna do with us. You see, the box with the skull was supposed to lead us to a really cool optional boss fight against a qunari ghost abomination thing. Instead, we decided to use the skull as a diversion to escape. So deciding that “dried blood counts, and as soon as it hits the blood on the floor it activates”, the room fills with fire and a large, angry, qunari mage ghost appears and starts wrecking everyone’s shit. We use this opportunity to quietly search the room for a secret passage out, since it’s aggro’d on the templars and largely ignoring us. One of the templars flees the room screaming “Captain! Captain!”, so we know reinforcements are coming soon.

Eventually we find the passage out – it’s under some flagstones in the middle of the room. Unfortunately, the qunari ghost ALSO finds the secret passage, smashes it open, and escapes the tower, leaving us in a room full of confused, angry templar. We also, at this point, hear more footsteps coming from the hall, along with Captain Dana’s angry voice proclaiming “THEY FUCKING DID WHAT??”. Figuring we’d take our chances with the abomination we just unleashed on the world, we all jump down the hole, outrun the templars chasing us.

Reaching the end of the tunnel, with templars in hot pursuit, we examine our surroundings. Down the hill, we see that everything is on fire, the abomination is tearing people apart, and there is so, so much screaming. After the briefest of pauses to consider the morality of our situation, we decide to leave Ostwick to it’s fate.

On our way out, someone does find us, though – a random citizen who thinks we’re here to help since we’re all still dressed as templars and a Circle mage. The GM’s last plea to get us to go back and clean up our mess. He underestimated how awful of people we are, and we ultimately waited for the citizen to run away, decided that we’d just be arrested or killed if we helped and that “The templars probably have this covered. I mean, this is their job, so they’ll take care of this before it gets too bad.” So we continued to bravely run away.

We did make one last stop to finish our deal with the mafia, though. Since we couldn’t say the Commander wasn’t killed in the demon attack we caused, we didn’t not do what they told us. That didn’t exactly fly, though, so we just handed over all the gold we stole (much to Reginald’s dismay) and the mafia contact decided he was way too sober to ask what the hell just happened. Also, they never want to do business with us again.

Fredrick, after hearing the ghost-thing awaken in the room below him and seeing his comrades run off to fight it, decided that he was not getting paid enough for this and left the Circle before seeing what happened.

This part of the adventure was supposed to take three sessions. We bumbled through the entire thing in one sitting.

Our protagonists, wanted in multiple countries now and with a pattern of leaving piles of corpses and razed cities in their wake, are now camped in the woods, deciding where to go next. The GM wants to send us to Kirkwall, but decided against it since “They’ve been through enough, I don’t think they’d survive you.” So instead we’re off to where our talents for destruction might be put to better use. Like a warzone or something.

Advertisements

React JS

Before I talk about React, I’d like to talk for a moment about AngularJS. Angular was the framework we used during the previous development of VisualScheduler. At the time, it was new, it was interesting, and it offered features that we wanted. After working with it last time though, I don’t think I want to try using it again for a while. Don’t get me wrong, Angular is an amazing front-end library. It offers a ton of cool features and is definitely the right choice for lots of applications. I think the problem I had with it was that it was TOO fully-featured. There was just SO much there it became kind of overwhelming, and all of it linked together so learning one thing involved learning about a dozen other things. I’m sure once you get the hang of it, Angular makes for a great experience, but it has a bit of a steep learning curve attached.
So this time around, I’m switching to React. Unlike Angular, which had all kinds of back-end tools and features, React is JUST a view library. No frills, no extra tools, just everything to need to display stuff and nothing else. This means that I’ll probably have to end up writing a ton of my own logic into it that would’ve already been included in a more fully-featured library like Angular, but it also gives me the freedom and flexibility to write whatever I need to write without being constrained by some built-in feature.
React allows you to break up your page into what it calls “components”, which are basically snippets of HTML code with some logic attached to it on how they should be rendered based on the state of on the page. These components can be nested inside one another to create an easy to follow page hierarchy. As an incomplete example:

App Component render:
<div>
  <Navigation />
  <Main />
  <Footer />
</div>

Main Component render:
var posts = [];
//For each post in this.state.posts, add a component to posts.
<div>
  <SideBar />
  {posts}
</div>

Post Component render:
<div>
  <h1>{this.props.title}</h1>
  <p>{this.props.author}</p>
  <p>{this.props.content}</p>
  <Comments post_id={this.props.id}/>
</div>

...

Now I can demonstrate why React is pretty awesome. The example above has a series of blog posts, each with their own content, title, and comments. (The specifics of how they’re all laid out aren’t too important here.) Imagine if we wanted to make this page live update with new posts and new comments without having to reload the entire page each time new content came in. React will automatically take care of this.
React operates off of what it calls a “virtual DOM”. The short version here is that you can dynamically make changes to the virtual DOM, and React will alter and re-render ONLY the changed pieces of the real DOM. It does this by keeping track of a “state” in each component. Notice the “this.state.posts” in the Main component above. We can write some code that listens for new posts to be added. When a new post is detected, it’s data will be added to “this.state”, triggering a render. Only the Main component will be re-rendered to the virtual DOM, since only its state got changed. Once the virtual DOM is all rendered to, React looks for any changes that were made, and updates the page accordingly. A similar approach can be taken for comments on each individual post, and only the comments box for that post will get updated as comments are added. If this sounds familiar, it’s because React was developed by the Facebook team, and this is what Facebook currently uses.
React isn’t the solution to every problem. Unlike Angular, it’s only the VIEW portion of the Model-View-Controller (MVC) framework. It has no built-in logic for moving data around or handling inputs, so, as I said above, you’ll either have to write a ton of framework code yourself or use some third party libraries. (Meaning it’s theoretically possible to combine Angular with React…but I’m not entirely sure why you would want to do that…) I’ve ended up with a combination, writing some of my own stuff, but supplementing a lot of it with third party libraries. One such library I’d like to end on here is “React-Router”.
React-Router basically gives React a ton more power in terms of handling your entire site. It’s a client-side router that swaps React components in and out based on the current URL. So when you go to navigate to a new page, rather than make a request to the server and reload everything, it just shows the new URL and only renders the new pieces it needs to. This lets you, for example, keep the same header on every page, but only load the new page content as the user navigates around. It’s definitely helped me out some with VisualScheduler, as I can keep the user’s current schedule and applied filters as they switch between pages with relative ease. This also means that different sections of the application such as class searching, schedule generator, and calendar can all have unique URLs without breaking things.
Okay, that’s probably enough about React. Next time, we’ll talk about an application framework designed specifically to play to React’s strengths.

MongoDB and Mongoose

During the previous run of VisualScheduler, I’d looked very briefly into MongoDB as a database possibility. Really, it was just out of obligation, as we were definitely going to use MySQL since it was what I was at least sort of familiar with. At the time, I didn’t really get what was going on with a ‘NoSQL’ database, or how something like that would even work. I thought it was pretty cool the way you could store JSON objects directly, but I assumed that searching these objects would be incredibly slow and tedious.
While I don’t have any hard data about HOW fast searching in MongoDB is, I can safely say that it’s significantly faster than I was expecting, and I don’t even have any optimizing indexes set up yet. A search of all 28,000+ sections for all the sections in a particular subject looks like it completes in less than a second. (I’ll have to run some benchmark tests later to get better data of exactly how much time this takes, but it doesn’t seem any slower than the previous MySQL setup we had.)
The best part about using MongoDB is how much simpler it makes storing the data. No longer am I trying to normalize dozens of tables with many-to-many links between them! There is exactly ONE table (called a ‘collection’ in MongoDB) that stores all of the data. Many-to-many relationships are now just a simple array of values rather than a series of joining tables. All the hierarchical stuff from the UNM Open Data files that I’m drawing from gets flattened as it’s stored, so each section is it’s own self-contained ‘document’. The database turns out larger (due to lots of duplication of data), but it’s faster to update and search through.
Queries in MongoDB are also very straightforward. Queries consist of simple JSON objects, the simplest of which just states the field to look for and a value to match on that field. (If the field doesn’t exist in a particular document, the document is just skipped.) More complex queries are formed by chaining specific fields together, using certain ‘keyword’ fields that all start with a dollar sign, and by using an “aggregate interface” that allows me to group, map, reduce, and all kinds of neat stuff. Just like SQL, injection attacks are still possible, but they’re pretty easy to defend against unless a query involves the $where field, which executes JavaScript directly in the database.
MongoDB does not enforce structure. This means that I can shove any object of any structure into any collection I choose and the database will just roll with it. On the one hand, this is a good thing since I don’t need to worry too much about a strict structure to my documents and it leaves everything nice and flexible if things change in the future. (Unlike MySQL, where every time we needed to change something the entire database needed to be scrapped and re-built.) On the other hand, I lose the reliability that comes with such a rigid structure.
Not that any of that really matters since Mongoose, the npm library I’m using to interface with MongoDB, enforces a pre-defined structure on every object it handles. While this takes away from the freedom that MongoDB offers, it’s still leagues better than the previous setup in MySQL. Fields can be added and removed on a whim, type validation is taken care of automatically, and you can even add ‘virtual’ fields which aren’t saved to the database, but are instead used to make your API simpler and easier. (For example, if you were storing a first and last name as separate fields, you can set a virtual ‘full_name’ field that combines them automatically.)
So between this and Node, I’ve got the server and the database taken care of. Next up, we’ll talk about the view engine I’m using this time around.

NodeJS and Express

Up until about halfway through CS460, I had never heard of Node. A server running JavaScript was a foreign concept to me. I noticed that several of the teams were building their applications using Node, but I didn’t think to give it a look. We only had a few weeks to put together a product, and adding an additional learning curve didn’t seem like the smartest move at the time.

Now that I’ve been formally introduced to Node (through the same channels I was introduced to the previous setup I had – projects at work), it’s definitely growing on me. I’m still not fully versed in the finer points of it, and most of my code is an atrocious mess, but it’s pretty easy to get something that works up and running very quickly. JavaScript is an extremely forgiving language, and it’s not very strict in how you set things up. Almost as soon as I started learning how to set up and use Node, I started getting ideas on how to bring back VisualScheduler.

Node’s package manager, npm, is amazing. It’s incredibly easy to search for and set up dependencies using npm. If there’s any problem I have with it, it’s that it actually has TOO MANY packages. When I start looking for something specific, I inevitably end up finding about three or four very similarly named packages, and only one is the correct one. This isn’t always a problem, but it’s a little jarring at first. On the plus side, if there’s anything I ever need, it’s practically guaranteed to be in npm somewhere.

Speaking of npm packages, I feel I need to mention Express, which is a REST API framework for Node. (It’s the only one I looked at, but it’s not the only one in existence. KOA is another one that seemed pretty popular.) Again, it’s incredibly easy to set up, but I found out that it recently changed most of its syntax in version 4.0, so quite a few places online are outdated when I go looking for answers. Fortunately, there’s a package called “express-generator” which will automatically build a starting project for you. All the fiddly little details of initial project structure, the busywork of setting up server config files, and a bunch of other stuff is all taken care of with one command. It still needs to be fussed with and customized, but the initial hurdle is already done. One command and BAM! – Server set up and running. Compare that to last time with Tomcat, where it took us about two and a half weeks just to get started.

Express itself is pretty easy to work with, too, once you wrap your head around “middleware”. Pretty much everything you do in Express is considered “middleware”. Even the 404 page needs to be set up as “middleware”, it’s just the middleware at the end of the chain. My job is to set up all the junk that happens to requests between the request being made and the response being sent. There are quite a few libraries available that can just be plopped in with “app.use()”, and they just “work” when you do it. About the only thing I needed to pay attention to was the order in which I added them, since they all execute in a specific order.

Okay, that’s the server portion pretty much taken care of. But the server was only part of the problem last time. Java and Jersey were a royal pain to set up by comparison, but the other half of the equation was the database. I don’t want to run into the same problems I ran into last time with SQL and Hibernate. So database choice is pretty crucial. Fortunately, there’s a VERY popular database that seems to be closely associated with Node. One that I’d looked at briefly during my time in CS460, but I’d immediately dismissed it since I was more familiar with SQL at the time and the entire idea of how this database worked seemed like a strange and unruly concept when I first read about it…

VisualScheduler: An autopsy

I think it’s safe to say that VisualScheduler died pretty much as soon as the class ended. The team disbanded almost immediately. I attempted to sign us up for ABQid to get a sponsorship and continue production, but as soon as things started to get serious, (and we discovered that there were similar projects done by larger teams on larger scales) everyone abandoned ship. For the record, I can’t blame them.

And so, with just myself left on the project, and other things taking up my time, VisualScheduler had to be shelved. It was a great project, and I feel it could’ve gone a long ways, but there were quite a few things holding it back:

  • Complicated setup: Looking back on the setup we had, I’m amazed we got as far as we did. I’d never planned a project like this before, and the rube goldberg we’d setup wasn’t exactly as flexible as I would’ve liked. The SQL database we had was also a mess. At the time, it’d seemed pretty simple: Our database would try to match the structure of the XML file we were drawing from. Unfortunately, I also wanted to try using database normalization, which meant breaking things up into about a dozen different tables. Any query we made had to be a mess of joins and complex syntax. And despite all the attempts at optimization, it still ran really slowly. Updates sometimes took over a half hour. (Though I took out a bit about removing duplicates and it shortened the update time to three minutes.)

    Using Java was probably a mistake in the long run. It worked, but it was…messy. Jersey was a major pain to set up, Tomcat was very uncooperative, and Hibernate was very difficult to work with, even with the simple demands we had of it. None of us had ever used Angular before either, adding a massive learning curve to front end development.

  • I suck at leadership: I tried. I really tried. I’d like to believe that I wasn’t awful, but I’m pretty sure I wasn’t my teammates favorite person by the end of the class. We won because my team had some very skilled programmers on it. It got really bad with the aforementioned database. I hadn’t set up a great way to migrate new database structure changes, so I ended up just emailing new databases to everyone once in a while, which I imagine interrupted whatever they were working on so they could get it installed. I’d like to blame SQL for this, but it’s my fault for being a person who likes to tinker with things until it annoys people.

  • No flexibility: For a lot of our future plans, we needed to make lots of what we were trying to do generic and work for lots of different setups. Unfortunately, lots of our setup prevented us from moving forward with that. Most of that was a conscious decision on our part, due to our time restrictions, but it left us nowhere to go once the class was over.

  • That thing that happens to all programmers at some point: I re-opened the code base after about a month of not thinking about it. I had no idea what I was looking at. I tried to improve things, but I just ended up breaking the whole backend in the process.

So with all these problems, I had to take my name off of ABQid, hopefully giving the offered money to a team that had their stuff together. (And from what I saw, there were quite a few of those at the meeting I attended.)

I guess this means that VisualScheduler will never happen. Even if I start over, using the same setup is obviously a losing situation given how inflexible and confusing it is. I’d need something simple, some way I can do this alone. Some way to take all of this functionality and organize it into a much simpler setup using fewer components…
nodejs-dark
…hmmm…maybe it’s not over yet.

So what’s next?

Yeah, this blog kinda got abandoned pretty quickly. I guess other assignments and working on VisualScheduler kinda took priority. Anyway…

So we hit feature freeze a while back. I’ve been encouraging everyone to stop fussing with the code base for now unless it’s a dire emergency or they’ve got something simple to add. Lately, though, I’ve been compiling a list in my head of things that need to be done this summer on the project before we release it to the public. It’s starting to get quite long, and that October release date is looking closer and closer the more I think about it…I think we can get a good product together by then, though. Maybe not everything on this list, but at least a major functional release by that time.

What we’re showing at the final presentation is more of a prototype than anything else. A proof of concept. Before we release the system proper, there are some things left to do, and not all of them pertain to the actual project. Since not of it is scheduled out, and I don’t know if we’ll have the time to get all of it done, think of this more as a wishlist than an actual features list for the future.

Development Process Changes

  • JIRA: I had looked into JIRA before we started this project as it is a really nice system for organizing issues and keeping track of who’s doing what with a project and it’s what I’ve been using at my place of work. However, I was informed that, while it’s awesome to use, it’s a real pain to get set up. So I figured we shouldn’t bother with it for this class, as I wanted us to be more focused on putting together a working prototype than fussing with the management system for a week or two. However, with the class over and concept proven we should definitely start looking to use a more professional process for our development. We’ll have the time to set up JIRA to our liking.
  • Jenkins: Jenkins is a continuous build server that can be used to constantly rebuild and redeploy code as it is updated. It will really save us time in keeping the server up to date and help us catch anything that we might be breaking with updated code. Again, I only didn’t include it for the prototyping since I’m not familiar with setting it up and it looks like it might be a bit of a pain.
  • Formalized Coding Format Standards: Right now we’ve been playing it fast and loose with coding standards. Not much JavaDoc, everything’s kinda spread out, and everyone has their own way of styling their code. For a prototype this doesn’t really matter TOO much, but for a proper release we need to have a standardized code style, and a formalized way of handling certain situations like exceptions.
  • Repository Branch Management: So far, I think we’ve been doing a pretty good job with branch management on the repository. But that’s kinda because I’ve been handling 90% of it myself using SourceTree. Yeah, I’ve screwed up once or twice and had to send panicked emails to everyone not to pull or push to the repository until I could fix this or that issue, but those are few and far between. In any case, we need to move away from just me handling all the branch management nonsense and formalize a process that everyone will take when handling code issues.
  • Better QA: So far our QA has been pretty lacking. We’ve found a couple of last-minute bugs in the past week or so, but no one is really peer-reviewing code before it goes into production. Setting up JIRA and setting up a system of branch management will help take care of this.
  • Separate QA from production: Right now, when something goes to the server it goes directly to the main production site. While this isn’t an issue right now, it could definitely be one in the future if we make potentially unstable updates to the site that people are using. We need to create separate servers for QA and production to avoid this issue.
  • Weekly meetings: Everyone still working on this will be tasked to meet together at least once a week via Skype, Google Hangouts, or GoToMeeting. (Doesn’t matter which, so long as everyone’s using the same thing and it remains consistent.) We’ll be using these meetings to discuss the following:
    • What have you accomplished in the last week?
    • What are you planning on working on this week?
    • Is there anything blocking progress on what you’re working on?

    These meetings will typically be incredibly short (hence the online meeting rather than forcing everyone to drive places), and will often be the jumping off point for other topics we might need to discuss. Ideally these meetings would be daily, but since I’m not exactly in a position to pay anyone at the moment I think weekly is the better option for us.

New Features

  • Data paging: A pretty serious bug was recently discovered that could hold us back for a while – when generating potential schedules, some combinations of classes produce literally THOUSANDS of potential schedules. While the back-end handles this surprisingly well, the front-end chokes on the sheer amount that it needs to show and almost always crashes the browser. This is a tough problem to solve, as it means we’ll need to implement a data paging system to ensure that only a certain chunk of the schedules that get generated are sent back to the client. It would mean keeping track of individual sessions and periodically asking the server for new chunks when the client scrolls around on the page. I’m not sure how difficult data paging like this is to implement, but it certainly doesn’t sound very easy, especially with our setup as a REST interface.
  • Save and Register button on Schedule Generator: This was one of those features we just plain ran out of time with. We need to add a a Save and Register button above each of the shown schedules that will display a window just like the one we have above the manual schedule page now.
  • Company Email Server: Set up an email server to receive customer feedback and send out automated email alerts.
  • Email Alerts: Allow users to set a “watch” on a class they want, letting them know if a time or instructor has changed, or if a seat has opened for them.
  • User Accounts: Let users create their own accounts. While I originally fought against the idea of exclusively using Google as login credentials for our site, after seeing it in action with another project I’m willing to see the light on this one. Either way, letting users create accounts will allow them to set class watches and save schedules.
  • Saved Schedules: Allow users to save schedules to their account so they can quickly load, view, and edit them as needed.
  • Automatic Registration: This one would need permission from UNM to achieve, but if we get permission (and can pull it off) this is easily a feature we can charge for.
  • Premiums: We’ve talked about premium features in the past, but right now we have no method of restricting features to users and no method of accepting payments.
  • Advertisements: Set up designated locations for Google Ads on our website. While this won’t make us a ton of money (In fact, I don’t think this alone will make us enough money to maintain the server.) it should help with the cost of running the site at least a little.
  • Help: This entails a few things, but mostly applies to integrated help within the application. Things like tool tips or better design to let users know how everything works. A designated “help” section would definitely be worth making as well.
  • Separate Website from Application: Right now, our static pages and application are both run on Tomcat, so any minor changes to simple CSS or content on the static pages involves re-uploading the entire application to the remote server. I propose that we separate these two into subdomains: Run the “website” (the home page, the contact page, the about page, etc.) on http://www.visualscheduler.net and run the “application” on unm.visualscheduler.net. This might cause legal issues with UNM, so we’ll need permission first, but if we can do this, it gives us a format for adding new schools into the mix: Each school gets its own application in its own subdomain. The applications can pull from a common “core” project for any similar features they might have, but each would need to be built basically from scratch (since they’re all likely to have different information and organization structures anyway).

Misc Updates

  • Fix the :8080 issue: Right now, due to limitations with EC2 and tomcat, we are forced to put the port number :8080 into all our URLs. This is a problem that needs correcting if people are ever going to want to use this.
  • Meet with the UNM reps: There are a few things we need to discuss with the UNM reps. Namely concerning making money off of visual scheduler, but also about the possibility of incorporating automatic registration into our system.
  • JavaDoc and other documentation: I don’t think this needs much explanation, but it needs to be done.
  • JUnit and Selenium Tests: Again, I think this one doesn’t need much explanation. Unit testing our system is the best way to ensure that new changes don’t break existing features.
  • Use Amazon RDS for Database storage: As of right now, we’re using a MySQL database that’s set up on the same machine as the server. This can be problematic, as if the server goes down and needs to be reinstalled, we lose the database as well. (This has happened once already.) Storing our database in an external source like Amazon RDS, however, gives us flexibility in this regard.
  • Finish and update static pages: Not gonna pull punches here, right now the static pages are terrible. We need to remake these to load faster, look nicer, and use better images.
  • Changelog and Release Notes: Here’s something that we need to put together – a release notes page that details what was patched and when on the application. Once we get it started it shouldn’t be too bad, we just need to make sure that everyone who works an issue puts a note into the release notes page when they’re done.
  • SoSoSoSoSo Many Bugfixes: Tons and tons of little bugfixes and upgrades that will compound on us unless we go after them.

Weekly Update (03/30/2014)

So I missed last weeks weekly update. Don’t really have much of an explanation beyond “I was lazy and forgot”, so let’s just move on to this week, shall we?

This week we’ve delved into adding functionality to the back-end and beautifying the front-end. On the back-end side, we have David adding new functions that return different types of queries. So rather than just a single URL that will return sections based on filters, we’ve now added several others that return just a list of subjects or campus’. These will be useful for dynamically filling drop-down menus and making any kind of custom queries we need.

On the front-end, Zach and Kellen have been working on making the page look as close to the mockup as possible, and so far we’ve got some partially formatted pages and some working tabs. It’s starting to come together, but there’s a very long way to go.

As for me, I’ve had to devote this week to another project for an animation class. I did, however, fix a critical issue with instructors and meeting times before I started on that, though, since that issue has been hindering progress for quite some time. In any case, I’m very grateful to have a team that I can count on to hold down the fort and continue to push this project forward while I focus on other things for a little while. This week, I’ll be shifting focus back to this project and revising the filters object we’ve been using into a “Search Terms” object that more closely resembles the way the filters work in the mockup.