Curveship

An Example: Artmaking

Here is a complete, very small fiction/game in Curveship. This single page of code defines exactly one actor, one room, and two things, one of which is a "generic" thing and other of which is an instance of a special subclass, "Art." Despite being so simple, Artmaking can be won and illustrates something about how concepts work and how they differ from the world.

'Artmaking, a tiny demonstration game for Curveship.'

__author__ = 'Nick Montfort'
__copyright__ = 'Copyright 2011 Nick Montfort'
__license__ = 'ISC'
__version__ = '0.5.0.0'

from item_model import Actor, Room, Thing
from action_model import Modify, Sense
import can
import when

discourse = {
    'metadata': {
        'title': 'Artmaking',
        'headline': 'A very simple example',
        'people': [('by', 'Nick Montfort')],
        'prologue': 'Settle for nothing less than an artistic breakthrough.'},
    'spin':
    {'commanded': '@artist', 'focalizer': '@artist', 'narratee': '@artist'}}

initial_actions = [Sense('ogle', '@artist', direct='@studio', modality='sight')]

class Art(Thing):
    '@sculpture is the only instance.'

    def react(self, world, basis):
        'Win the game when smashed.'
        actions = []
        if (basis.verb in ['kick', 'strike'] and basis.direct == str(self)):
            damage = Modify('puncture', basis.agent, direct=str(self),
                            feature='intact', new=False)
            damage.after = """finally, a worthy contribution to the art world
            ... victory!"""
            damage.final = True
            actions = [damage]
        return actions

items = [
    Actor('@artist in @studio',
        article='the',
        called='artist',
        gender='female',
        allowed=can.possess_any_item,
        refuses=[('LEAVE way=(north|out)', when.always,
                 '[@artist/s] [have/v] work to do')]),

    Room('@studio',
        article='the',
        called='studio',
        exits={},
        sight='a bare studio space with a single exit, to the north'),

    Thing('@box in @studio',
        article='a',
        called='box',
        open=False,
        allowed=can.contain_and_support_things,
        sight='the medium-sized parcel [is/1/v] [open/@box/a]'),

    Art('@sculpture in @box',
        article='a',
        called='sculpture',
        intact=True,
        sight='a sculpture of a mountain, made to order in China')]

Staring this game and typing concept @artist tree shows the artist's concept:

@cosmos: nature []
    @studio: studio [of]
        @artist: artist [in]
        @box: box [in]

The artist doesn't know what it is the box. There is something in the box, though. You can see this by typing world tree or by typing open box and then look in the box. It's a sculpture. Now, typing concept @artist tree gives a different result:

@cosmos: nature []
    @studio: studio [of]
        @artist: artist [in]
        @box: box [in]
            @sculpture: sculpture [in]

The artist knows that the sculpture is in the box, and this is represted in the concept. After opening the box, type close the box followed by look at the sculpture. "You are unable to look at the sculpture because the sculpture is not visible." That makes sense, since the artist just closed it up in the opaque box once again. Check the concept again by typing concept @artist tree, and you'll see that the sculpture is still in the concept. The artist knows (or believes) that the sculpture is in the box, even though she can no longer see it.

That's about as much excitement as we can get out of this tiny game, but there are two other things to mention: First, the actor's "refuses" attribute is what produces a refusal when you type go north to leave the studio. The artist can't really go north - there are no exits from the studio defined - but this makes it seem as if it's the artist's will that is keeping her in the studio, and it provides a reply that is in keeping with the room description.

Second, Artmaking can be won because smash sculpture or a similar command causes a reaction. The sculpture is punctured by a Modify action, and this action is marked as final (damage.final = True). When it's returned, it gets narrated and then, because it has been marked as the final action to simulate and narrate, the program terminates.

Main Curveship Page