This file describes ideas that come out of meetings and out of your head. Feel free to elaborate on anything, restructure, organize, whatever. Negative comments are also fine, but try not to delete ideas. * Rooms can be made into objects to unify and simplify the language. One of the big problems with Inform is that all these game-specific features are built into the core language (such as the concept of darkness), and it ultimately limits the kind of game the programmer can make. We can then have different classes (types) of objects (such as rooms). Then subsets of objects can be selected according to type. Objects can have multiple types. Sort of like a loose OO where all objects are singletons. * Containment is only one kind of relationship between objects. They could also be joined together, for example, or perhaps mixed. Maybe thinking about the various physical relationships between objects in the real world is helpful. This could also be extended to relationships between characters (love, hate, envy, etc.). * It might be nice to have some standard templates for reused parts of games (rather than incorporate them into the language). Inform has kind of a mix here, with a standard library and also many game-specific features in the language (as noted above). Furthermore, since these reusable parts are just Petri nets, it should be possible to allow the programmer change them such that they connect up to the rest of the game appropriately. This is a means to eliminate redundancy, and also prevents the programmer from being locked into certain ways of doing things. * Any presentation of data to the player should be done external to the Petri nets, and algorithms for generation of this data should also be as external as possible. For example, strings should be external so that they can be translated easily, but this also means that algorithms to sort lists of strings should be external, particularly since this ordering will change depending on the language used. Also, if a sentence must be constructed from sub-parts, as is common in interactive fiction languages, this should also be external. By the same token, the parser that the player interacts with should be external and it should generate a canonical form of any action for the game engine to interpret. In essence, only those things that are necessary for verification of the game should be incorporated into the Petri nets, to simplify the verifier's job. At the same time, no actions that the player can take at runtime should be left out, to make sure that the properties proven or disproven by the verifier always hold during gameplay. player --> parser --> petri net --> output driver --> player * Breaking a narrative into disjoint puzzles in a kind of hierarchical Petri net form might allow for verification of sub-components and hence give speedup. * Furthermore, moving global counters out of sub-puzzles and treating them specially might afford some optimization. * Counters can be seen as a necessary evil, at least to reproduce the functionality of games, but they're probably quite expensive to incorporate into verification attempts. * Some kind of optimization passes on the generated Petri nets prior to solving might be good, except that it's also possible these optimization are provided by BDD's regardless. However, it might be nice if the difference between +x.y and +?x.y was hidden from the programmer. * We really want to allow anything here, to encourage new ways of doing things. For example, it would be really cool to have a collaborative two-player interactive fiction game, which hasn't been done before because the underlying game engines and languages prevented it. Actually, the pnfg language was already designed with this in mind. The fact that most computer narratives are first-person is not embedded in the language---you need to explicitly define the player (eg 'you' in many of the examples), and actions are directly predicated on that symbol (eg '(you,take) { ...}'). This is easily generalized to common or separate rules for multiple subjects (and can already be parsed). There are still 2 things that would need to be done: 1) some way of feeding multiple streams of events to the common petri net structure is required (not hard, but it's not there now), and 2) a level of atomicity (and perhaps sync constructs) would have to be added. Set, move, output stmts are already atomic since they'll execute by firing just one transition. Conditional tests themselves are also atomic. * Analyzing narratives for different properties than just playability is possible. For instance, some of the simplest adventure games do not allow you to drop items, or do any particular action that would imply negative progress toward the game goal. These narratives admit a greedy search strategy, and so it should be much easier/faster to analyze the resulting nets. It may be possible to identify such games by examination of the individual action sequences, and perhaps even use this to help define a measurement of game difficulty or complexity. Identifying subsequences of such behaviour would also be useful for decomposing the net. This is orthogonal to a hierarchical division by puzzle or region, but obviously related. It may also just reduce to the idea of optimizing subsequences of the petri net by collapsing or summarizing their behaviour. * AIFT and the documentation available for it online are a good source of ideas, AIFT being the closest thing out there to this project (it's written in Prolog). We also have the AIFT source code and we can license it how we want. * It would be neat to look at turning the possible set of player actions and paths at runtime into some kind of control flow graph. The current nfg's don't really lend themselves to this kind of visualization because of the idle state and because of all the internal transitions. Would require a BFS over player actions. Maybe it's more like a flow chart than a CFG. * Context-specific actions. In a broad sense, room-specific actions are actions that are only available given a specific context, i.e. the player must be in the declaring room. This can be generalized so that some actions are dependent on the game being in a specific state, and simply not available otherwise. This appears to be a better way of getting error messages for invalid actions (e.g. 'Eh?'). Also, it will limit the number of available moves when "query moves" is done. * Assertions. It would be pretty neat if the programmer could specify assertions in the .pnfg files. These could lead to an assertion failure exit state (possibly different from losing), or they could lead to generation of invariant specifications for model checking (if we decide we don't want to specify, "reaching the assertion failure state is not possible" as our invarspec. Additionally, these could be included for debug builds only. * Room actions extending instead of overriding. It would be neat if you could specify a global action, and then inside a room extend it instead of override it. * Calling other actions internally. When you enter a room for the first time, you might want to print the long verbose description that you get when you type look. It would be cool if instead of duplicating the text, you could just have (you,look); as a statement or something. There should be no corresponding action transition generated or fired though... this action should not be visible when winning or losing solutions are printed. Examples: 1) room Foyer { state { visited } enter { "Foyer of the Opera House"; if (Foyer.!visited) { +foyer.visited; Foyer (you,look); } } (you,look) { ... } } 2) (you,remove,cloak) { ... } room Bar { (you,remove,cloak) { if (Cloak.carried) { "You stumble around in the dark."; Bar.message++; } else { global (you,remove,cloak); } } } * Enumerations. In CoD, the cloak can be in three different states: worn, carried, and on the hook. However, they are mutually exclusive. It would be nice to have something like enum { hook, worn, carried } available. This requires only 2 boolean variables instead of three. * Automatic detection of illegal states. In CoD, there are actually two variables for the cloak: worn and carried. However, (Cloak.worn && Cloak!.carried) can never be true. Maybe we can detect this with an analysis somehow. * Two types of scalars: saturating and wraparound. If you do ++ or -- at the end of a counter's range, what happens?