Coding in Tidepool is a mostly declarative affair, where players define rules for agents to follow. The design comes from my own Gravity environment from the early 90s, which itself was influenced by Prolog and Smalltalk. A more modern sibling might be SPARQL or Wolfram Language. Unlike these others, I’ve decided not to name the Tidepool language, since I want there to be many dialects that do the same things.
As of now, Tidepool rules are too syntax-laden for most kids to use. This will change in the next milestone when I make the cognitive agent’s natural language interface. For example, this current clunker:
- #adv-bird.1 when “get” nearby(#adv-rod.1) or holding(#adv-rod.1), say “The bird is frightened…”
could be written in any of these ways:
- bird, when I say “get” and the rod is nearby or I’m holding the rod, say “The bird is frightened…”
- bird, instead of get say “The bird is frightened…” if I have the rod or it’s nearby
- don’t get the bird if I have the rod or it’s in the room, say “The bird is frightened” instead.
Tidepool’s current coding UI is also more complicated than I’d like. Instead of typing the rule above, you can also use the Rule Box.
The puzzle I’m currently working on is defined like this:
This basically says, “Bird, when I type “get”, if I’m holding the rod or the rod is nearby, say ‘The bird is frightened’. If the rod isn’t nearby and I’m not holding it but I’m not holding the cage, say ‘You can catch the bird, but you cannot carry it’. If you are holding the cage and the rod isn’t near and you’re not holding it, then get the bird.”
There are many ways to express conditionals like these, and yes, this is too complex for kids. The structure above is merely the boiled down version of a much fuzzier future. I’m hoping you can use real language to write rules by March or April.
In Java/C/etc, this would be written:
if ( holding(aRod) || nearby(aRod) ) say( "Bird is frightened"); else if ( !holding(aCage) ) say( "Cannot carry it" ); else get(aBird)
Yes, a programmer will think this is so much easier. Good luck teaching this to a seven year old. Besides, declarative rule-based languages have deeper strengths that static procedural if-else chains can’t touch.
The two biggest parts of a software design are the architecture and the object model. The architecture governs how pieces interact and communicate. The object model details the pieces themselves, the data buckets, the nouns we use as we talk about a business.
Tidepool’s object model currently has 19 entities (only 12 detailed below), each of which has its own database table and DAO (data access object). For example, “rule” entities can be accessed through the SbRuleStore DAO, which works with the SbRule table in the MySQL database.
Many programs access the database directly, which is perfectly fine, but it limits your options. By adding a DAO abstraction layer between your code and the database, you can simplify things over time or do wacky redirection stuff like I’m doing.
The Tidepool DAO connects to two different databases: the local Derby database and the remote server database. When you save data, it first saves it locally, then queues an update to the server. When you search data, it looks only at the local database, which is much faster. The beauty of a DAO is the rest of the code doesn’t need to know this. With a flick of a switch, I can work local-only (when you’re disconnected from the Internet) or directly with the server.
Technically this DAO approach is part of the architecture. It enables the object model, which consists of the entities, their fields, and how they connect to each other, as detailed in the chart. The model is merely an abstraction, which I could implement it with many different architectures.
For the curious, I’m using JPA (Java Persistence API) to do object-relational mapping both locally and on the server. All queries exist as methods in the DAO, so these details are hidden. The communication between client and server can easily switch between Remote EJB and JAX-RS. I implemented both to see which I liked better. Currently Remote EJB is winning, but when we port to tablets, we’ll have to use JAX-RS.
Without question, I’ve spent too much time on Tidepool Adventure, my game-within-a-game tribute to the 1977 classic. Were I my own objective project manager, I’d have said long ago, “Move on.” Between parsing the original Fortran data file and adding features to get gameplay to work, Adventure’s been a project all its own, one likely a distraction at best.
So why have I stuck with it? What value does Adventure bring to Tidepool to justify this extended detour?
The best reason for Adventure is that it’s a non-trivial development example for all of Tidepool. It proves what can be done, using someone else’s game design, which forces me to say, “Ah I didn’t think of that, I need to add this and this.” Adventure’s been part of the plan from the start precisely because I knew it would guide the design of Tidepool in ways I couldn’t anticipate early on.
The next reason for Adventure is that it’s a great template for players to modify and extend. Colossal Cave has a long history of new versions, starting with the Don Woods one. My goal is to encourage players to make changes over time. Adventure (and MUDs) lend themselves to spontaneous extensions.
The last reason is to honor this ancestor of all story-based games. Colossal Cave Adventure was a big part of my early experience with computers. I’m sure it’s influenced my software designs over the years, even my general thinking. Exploring a huge state-machine like this is a true cognitive playground.
All good reasons, but now I want out of the cave. Perhaps today will be the day.
I work for myself, but I still have a boss. That which governs my days is neither human nor corporate. It exists as bits on a hard drive in northern Virginia, on a server named Vesta, in a program called JIRA. My boss is The Board…
Called a kanban board for a practice in Japan, my JIRA board (http://board.playtidepool.com) shows the state of my mind, with past accomplishments on the right, current quandaries in the middle, and future headaches on the left.
Above is a mostly green line that shows the milestone at a glance. Green is done, yellow is now, red is what’s left. The red may seem bigger than the scheduled nine days might allow, but that’s by design. I always add “nice to haves” in case there’s time left over, which there never is.
Anyway, enough chatter, the board beckons.
Yesterday while tracking down the bird bug, I used an incredible tool called Dynatrace, which gathers fine-grained metrics from running applications, then lets you analyze your app in myriad ways. Dynatrace is very expensive, designed to run full time on large server apps like American Airlines and Bank of America. I’ve used it to consult for companies like Marriott, Lowes, and Dollar Thrifty.
While technically an “application performance monitoring” tool, I often use it for debugging because it gives unparalleled visibility into the state and history of running software. Below is a “purepath”, a sort of stacktrace on steroids, which details the exact path your code took for a specific action.
Two things to note. First, this is an end-to-end trace, meaning it shows me the detailed path from Tidepool, the client, to Storymill, the server, and back. Second, it’s giving me exact timing information for individual method calls and network hops. I can then aggregate days or weeks of this data to see the sore points in my code.
I’ve wanted a tool this powerful for most of my professional career. The visibility it gives on running code blows logging and breakpoint debugging out of the water.
I start today trapped in the Bird Chamber of Colossal Cave, trying to fix a bug with the bird. Seems whenever I make a change to the bird, it creates not one but two copies of it in the databases.
The first copy is expected. Tidepool uses automatic version control, with automatic branching. Whenever you change something on the “trunk”, it creates a branched version with your username. You can later “push” your changes to the trunk to make them public or “reset” things to discard your changes. This behavior works everywhere except the Bird Chamber. Changing the bird creates two copies in the database.
Once I solve this “blocker” bug, I’ll be able to finish the puzzle in this room, then move on to the last two puzzles I plan to implement in Colossal Cave before moving on to the next big feature, the improved Map UI. All together I’ll have coded 18 of the 94 rooms in Adventure, the eight above ground and the ten you can reach before solving the first hard puzzle in the Hall of the Mountain King.
For me to finish Alpha 4 and Alpha 5 before Devoxx, I need to move on from Colossal Cave, where I’ve been stuck for quite some time.
Another event, another Tidepool push: 33 days to finish Alpha 4 & 5 before @Devoxx so I can show Java devs my game world & cognitive agent.
Tidepool Plan 814 … release Alpha 4 on Feb 27th, Alpha 5 and Indiegogo campaign on Mar 20th, Alpha 6 on Apr 20th, and Beta 1 on May 20th.
We’ll also conduct an eight week “Alpha Pilot” with 50 schools in 50 states between March 27th and May 19th. Invitations get sent Feb 27th.