Showing posts with label web coding. Show all posts
Showing posts with label web coding. Show all posts

2014-11-17

My first Android App: FantaGen

UPDATE: FantaGen has added many more generators since its first release. Some fun, some serious and all very expressive.

I made FantaGen - a fantasy name generator to experiment with exploring cultural spaces with random generation. There are other generators so I aim for FantaGen to stand apart from the competition by being more comprehensive and more expressive.

You can get FantaGen from the Play Store

These types of generators are good for a bit of harmless fun but they do have a serious side to them. You can use the generator to help break some writer's block.

There are two cultures that have strange names: Simptee and Star Spirits. These were based on a simpler generative name system from a now abandoned interactive fiction project. It made sense in that story to have characters with names that weren't always the same. I thought the names were kinda cool so into FantaGen they go. Code recycling is good.

There are tons of fun image-based generators doing the rounds at the moment. These usually take the form of having the reader build up a name by looking up alternatives based on letters in their own name or their birth month. While these are fun for a single lookup, they don't give much variety for doing 10 random names at a time. My own feeling of these is that 26x26 alternatives is simply not rich enough when the user can see ten items at a time and refresh every half second. Significant extension to the generator is needed to add enough variety to be interesting.

I'm particularly proud of Fairy Names and Star Spirits. Fairy names uses both vocabulary words and syntax variety to create fun diversity. When I can picture the character that goes with the name then I think the effect is good. The Star Spirits mix both words and syllable combinations to represent their angelic like culture. The syllabary is fairly restricted to match how I image their angelic language to be so the word-based titles help to create the variety.

The Roman name generator combines a syllabary with some real Roman names based on research. The syllable based names are most likely anachronistic nonsense. Though it would take much more work to do a historically accurate Roman name generator given how complex their naming patterns are. In particularly I don't handle the gender very well at all: Claudius / Claudia, Julius / Julia. I would like to do more name generators based on real cultures since that ties into my semantic web interests.

Speaking of interests; this project also represents an interest I have in generative creativity. I want to be doing actual research into generative graphic design tools once my PhD is complete.

FantaGen is free and always will be. I have plans to continue extending FantaGen. As the list of generators grows I can see some ripe experimentation in how to navigate that space to keep things fun. I'm open to suggestions for new generators too.

2012-11-04

Joust Conversion for Twine

Here is a conversion of Joust. This is another one of those games I copied from source in a book to learn how to program as a kid. Bringing these old games back to life is like paying my dues.

This is not a difficult game - you will play through it in just a few minutes. There is also not too much in the way of flavour text compared to other games. I'd rate it as about the same as Highnoon in terms of depth but the game play feels much less varied.

SPOILER: Once you work out a winning attack / defense combo then keep repeating it and let luck do the rest.

The game logic is entirely implemented in Twine/twee code. This could've been much simplified by using custom javascript macros to handle the logic branching or even by coding a "switch...case" macro system for twine to substitute for "ON X GOTO line, line ..." code from the original. I used if, else, endif blocks and despite being a bit complicated and verbose they did handle the task well enough.

Debugging something with such tricky logic wasn't easy but I used a couple of tricks. These might be useful to other Twine/twee code authors too.

TIP1: Debug nested if, else, endif blocks by copying into another text editor and indenting like a regular programming language.
Complex nesting of if, else, endif blocks can be annoying to debug. The are formatted in non-obvious ways to suit the needs of end display, not the programming. So, just for the purposes of debugging, try indenting it as if it is a programming language.

TIP2: Debug nested <<display>> chains with html comments. e.g. <html><!-- PassageNameX --></html>
Chasing around through multiple display macros gets hard. Add html comments to insert invisible stuff into the code so that you can inspect the page and track where the display macros are leading. It helps narrow down where the bugs are really quickly.

Checkout the other games I have converted

2012-10-28

Camel Conversion for Twine

Here is a conversion of Camel. I can vaguely remember coding and playing this game as a kid in the early '80s. If it left that kind of impression then it must've been a fun game so I decided to give this a shot for a Twine conversion. It is similar in many ways to Highnoon in that there is an underlying game system represented by some quirky text.

The game play can be frustrating! Oases appear frequently enough that water is almost never a problem (just don't forget to drink). The biggest problem is the pygmies. They have a 10% speed advantage on your moderate speed, but running your camel at full speed burns it out three times faster.

SPOLIER: The mathematically optimal strategy is to go full speed twice, moderate speed once then rest. Drink when warned (actually the turn after). If you are captured then wait for the ransom. Even with an optimal strategy a win is not assured. In this game the player loses more often than not. Prepare for frustration.

I made extensive use of the custom macro <<randomp>> that I made for another project. This simplified a lot of the handling where things were triggered by random events.

I intentionally left as much logic in place as it is in the BASIC code with a couple of small changes. The capture submenu display the request for sub-command before the menu and the "Miles travelled" text appears more than in the original. There was also something where asking for a status report would fall through to also taking a drink. I assumed that this was a bug and changed status report to not force a drink at the same time.

From the viewpoint of 2012 the text could appear offensive. I prefer to think of it is ironically anachronistic because there are many obviously mismatched facts and intentional mispellings. Many of the other books edited by David Ahl do contain some quite detailed information about the historical context of the games so I do not assume the authors of this game were naively flavouring the game they way they did.

Checkout the other games I have converted

2012-10-22

Nicomachus Conversion for Twine

Here is a conversion of Nicomachus for Twine. This was a much simpler program than Highnoon so I further restricted myself to making all program logic happen in Twine's tweecode.

Twine surprised me with its arithmetic handling. Up until now I had been ducking into Javascript for all but the simplest of expressions. Twine was easily able to handle an arithmetic statement with three sets of parentheses and about six terms.

Twine does lack a loop function (like a while). I was able to simulate this with an if, else, endif macro that keep displaying another passage (itself) until the condition expired. You can check the code for how I implemented this. The technique is known in computer science as recursion.

The verdict; A fun quick conversion.

Checkout the other games I have converted

2012-10-07

Highnoon Conversion for Twine

This week's creative project is a conversion of Highnoon for the Twine interactive fiction system. While I was converting/reimagining for Arduino I had two thoughts. The first was that I'd like to do a more faithful conversion with the original dialogue and secondly that such a conversion would be a way to demonstrate the power of Twine.

So, you know the game; You're in a showdown with Black Bart. You each have four shells and are 100 paces apart. In this original version there are more win/loss conditions than straight death.

Twine allows quite a lot of expressiveness and flexibility when writing interactive fiction. It also outputs the results to a single .html file that require no supporting libraries or other files. If you are interested in the basics of Twine then I'd suggest looking at this tutorial.

The conversion to Twine was fairly straightforward. I used the Jonah Story Format because it places passages one after the other without clearing the screen like Sugarcane does. I made a few tweaks to the inbuilt functions; the first to totally suppress the output of passage titles and the second to totally deactivate old choices. This was not difficult; it was more a matter of removing the bits of code from existing functions that I did not need.

I also based passage names around the line numbers in the original code. This eased moving from the GOTO style of the original code to the structured coding style of Twine.

The verdict; a very playable old-style game.

Checkout the other games I have converted

2012-08-28

PhD Progress Report to August 2012

It's been awhile since I have posted on this topic so here's what I've been doing with my PhD. I have since made several improvement to the semantic web browser described in my last PhD update and have been experimenting with techniques to reduce information overload.

Reminder: My research tries to reduce information overload when displaying data where the structure of that data is not known ahead of time.

There is a good body of research in linking determining how related text strings are by meaning (the linguistics meaning of semantics). The problem for me is that the speed is not fast enough for building displays at runtime in a web-browser. I instead went with lexical methods that use naïve rules to just compare characters in a label. There are well establish algorithms for this; Dice, Levenshtein to name a two. My implementation of Dice in Javascript is now in the WikiBook project called Algorithm Implementation

What is not immediately clear is how these algorithms should determine similarity when two triplets with labels resolved are compared. Assuming that the subject is equal/equivalent then just how does x->firstname:John relate to x-->surname:Xeedown? My most recent chapter took Dice and Levenshtein string similarity algorithms and then compared an averaging of the predicate and object similarities versus simply taking the higher of the predicate or object similarities. I conducted a study with twenty human participants and have analysed the data. The data is indicating that a naïve lexical algorithm can give acceptable (i.e. “usefully better than random”) results in line with what human participants would say about the same triplet pairs. This is encouraging.

In that study I also tested any algorithm for determining if triplets were redundant. This is used to subsume (not display) triplets when it is deemed that other triplets contain equivalent information. I already had built such an algorithm using intuition and voodoo – and the testing on humans indicates that the algorithm is usefully better than random at matching what humans also rank as redundant data. This is also encouraging.

Using the redundancy algorithms I now manage to avoid displaying quite a number of triplets. In some cases, using data from dbpedia, about 55% of triplets are simply not displayed because they contain redundant information or are turned into lists.

I also used the similarity algorithms (actually the inverse) as the distance metric in hierarchical clustering of triplets. The cluster hierarchy is then flattened which results in groups of related triplets. While not giving perfect results, for a “first naïve attempt” at grouping triplets the results appear to be better than random – though I have not tested this.

I am currently writing up research results and learning tons about statistics as I go. It is particularly interesting to read about the debates in statistics for multi-rater agreement in Likert scales. After trying to come to grips with so much math I eventually went with the old method of just just looking at the shape of the of raters histogram.

Going forward from here is the next chapter. This one leaps off from the “first attempt” approaches described above and attempts to find algorithms that learn the user's preferences for ordering, grouping and redundancy. Recommender systems research has some particularly interesting avenues to explore here. I currently invisage a conversational User Interface that allows the user to express their data display preferences (order, grouping, redundancy etc) via direct manipulation.

The performance of any algorithms found and adjusted will then be tested against human raters. Once that study is complete I then theoretically switch into “write up” mode for the thesis but will need the ocassional coding distraction of actually implementing the results of the studies into Eme. Things are looking promising.

2011-01-02

Solano Slider

So I've been playing with the Solano slider v0.8 jQuery plugin for a friend's website. Her website uses many (around ten) image sliders that are CSSed exactly the same. I wanted to create something that is as easy as possible to update and that keeps the HTML code very clean. There were a few gotchas.

Solano slider can automagically setup numbered navigation for you if you supply a #div. Well everything in that <div> will be floated so you must set a height in CSS or it won't show any navigation. The slider navigation must also be a <div> because Solano creates each navigation item as a floated <p> element.

Solano slider will also float each of the images contained within the slider so you also must set a height on the container <div> in CSS or it won't show any images.

When using jQuery1.4.3 there was a problem with the positioning of images and my left-floated site navigation. This was fixed by simply upgrading to jQuery1.4.4.

I use multiple image sliders in a single page and found the way that Solano handles classes added to navigation items and the currently selected item to be a pain in the butt. What it does is each slider gets a separate class (.solanoNav1, .solanoNav2, .currentNav1, .currentNav2 etc.) It did not add a generic navigation or selection class that could be used to style everything globally.

To ease updating of the website later (i.e. adding more sliders) I run the slider creation in a loop that runs over an array containing a list of slider #id. I did want to use a jQuery .each() e.g. $('.slider').each(...) to automate this without an array list but jQuery apparently doesn't allow .each() to be nested and Solano uses an .each() internally to build the slider. Still, adding a single entry to an array list is not too onerous an overhead for each new slider. The code is:

var sliders = Array('sprodesignad','strevormorris','smasterhouse',
  'smasterwok','shermagazine','sphotography','swallpaperdesign',
  's30day','sexperimental','suntitled','slost');

for (slider in sliders) {
  var sthis = $('#' + sliders[slider]);
  var navid = sliders[slider] + 'nav';
  sthis.addClass('slider');
  sthis.after('<div id="' + navid + '" class="slidernav"></div>');
  sthis.solanoSlider({
    autoNav: true,
    navID: ('#' + navid)
  });
  $('#' + navid).children().addClass('solanoNav');
  $('body').append('<style type="text/css">.currentNav'
    + slider + ' { color: #ccc; }</style>');
}

First we get a jQuery reference to the slider and setup a standard name for the navigation <div>. Next we add a .slider class to every slider to make hooking CSS easier and to further reduce the burden on the HTML coder when the site is updated later. Next we automatically add an empty div for the slider navigation using the name created before. The next call creates the solano slider - using the autoNav option and supplying the navigation <div> #id we created before. The next two lines are hacks to make dealing with all sliders globally easier. We add a standard class to each of the navigation items to make styling them easier. Finally we kludge in a <style> element containing a rule for the .currentNavX (.currentNav1, .currentNav2 etc.) This ends up polluting the DOM with a bunch of <style> elements and violates general practice of not specifying CSS style info in the HTML file but could not be avoided without hacking Solano slider itself.

Maybe I should just hack Solano? Would the author mind? Can I also just mention just how much I love jQuery!