intfiction.org

The Interactive Fiction Community Forum
It is currently Sun Nov 19, 2017 5:25 am

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Tue May 23, 2017 3:10 pm 
Offline

Joined: Wed Aug 26, 2015 11:18 am
Posts: 87
Location: The Netherlands
Hello all, I made a new version of the XVAN authoring system. And there's also a tutorial now on how to write a story from scratch.

It can be downloaded here

I appreciate all feedback.

-edit: link updated to latest version

-edit: link updated to latest version

- edit: link updated to latest version


Last edited by Marnix on Tue Oct 24, 2017 12:26 pm, edited 4 times in total.

Top
 Profile Send private message  
Reply with quote  
PostPosted: Thu May 25, 2017 7:46 am 
Offline
User avatar

Joined: Sat Jun 25, 2016 12:13 pm
Posts: 152
Hi Marnix,

Great job on your latest XVAN release. I think the documentation is great, something sorely lacking in many other systems.

I have some feedback/suggestions/requests;

Base library; lib.xvn

Is it possible that you could make a "common library", ie "lib.xvn" that contains "standard" definitions of the usual verbs, flags, triggers etc.

And that games could just include this library to get started.

Going through your docs, you progressively make verbs like "get" better and better, handing all the cases and eventually cope with ambiguity too. This final version should be part of the lib, so that people can go right ahead and use this final version. Same with all the other standard verbs, attributes etc.

Your demo games would be refactored to use this lib, so that for example COD would fit on a single page.

I think that would help people get started a lot.

In general, can .xvn files include other files. it would be nice, not just for a std lib but so that large projects could be split into sections.

Tools

Can xc (compiler) be changed to work with the command line:

Code:
xv [-o <output file>] [-d] [other options] <xvnfile>


The way it currently prompts for the file name means that it can't be added to an automatic build script.

There should be "debug" and "release" build modes (ie -d = debug), to add additional logging, tracing etc.

Also it would be nice to define debug verbs. For example; teleport and superget could be compiled into the debug version, but not release.

Embedding

This is a more wild suggestion, but it could be really useful;

Could it be possible to define functions inside the .XVN code that could be called from outside in "C".

For example, define some .xvn functions as "exported" and the xc compiler would generate .h and .c linkage files that would link to the runtime.

To make things simple, it would not be necessary to have full argument passing and return. The functions could, for example, take a string and return a string. I think this would be enough to get started.

Why?

Supposing one wanted to make a fancy UI over the top of an xvan system. Say i want to show the current location somewhere on that UI or i want to show the current inventory in a sidebar, or perhaps a list of people you'd met in the game.

The UI could call
Code:
string get_inventory("player")
or something, that would wind up calling into the xvan code itself to determine the answer.

A watered down version of this suggestion is to have a set of handy functions already part of the xvan runtime. So you don't get to define them, but there's stuff already for things like:

  • save/load game
  • get inventory
  • get known map
  • get current location picture
  • get/set property
  • eval command(string)

Those are my thoughts anyhow.

Good luck with xvan.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon May 29, 2017 2:17 pm 
Offline

Joined: Wed Aug 26, 2015 11:18 am
Posts: 87
Location: The Netherlands
Thank you for your detailed feedback. It gives me something to think about.

Including other files
The vocabulary file is/was meant to be sort of a library with all the words and verb code. But each author would add his own words to it so there would never be one version. I agree that it would be better to have one lib and put that under version control. And as some verbs do need flags (like 'open' needs flag f_open to test) the flags can be defined in the lib as well. Same for commonly used triggers like t_entrance and t_exit.
The extra verbs and words that the author defines for the story can than still be defined in a separate vocabulary file for that specific story.
I agree it would be nice to be able to split up files for larger games. For example, the Bronze port story file is 11,900 lines.

Tools
I think the command line options can be intercepted by using the argc and argv arguments from the main() program?
Hard coding the debug functions in the interpreter seems not like a very good idea. Suppose someone wants to implement a teleport function in the story they're writing and there is already a dubug function with that name. Maybe I can make 2 libraries one with debug functions and one without. The -d commandline option would then tell the compiler which library to compile.

Embeddding is something I would really have to dive into. I never made something like it before. If I understand correctly, with this your Brahman app could create a map and other graphical stuff for an xvan story?

Thanks again for your thoughts


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon May 29, 2017 3:39 pm 
Offline
User avatar

Joined: Sat Jun 25, 2016 12:13 pm
Posts: 152
Hi Marnix,

regarding debug compile, to be clear, i wasn't specifically suggesting there would be pre-defined debug verbs in the compiler or interpreter, but that a story could define its own debug verbs that would be marked as such (eg DEBUG keyword) and that these would only be compiled in with -d.

Of course, it could also be done with separate files for debug and release. But i think it would go nicer in one file and also the standard lib would support this with its own debug verbs.

a bit about the Brahman interface;

I've been steadily converging on a compact interface between a GUI front end and a self-contained game back end. XVAN is one of my experimental back ends.

Because i didn't want a proliferation of functions, various features evolved into a JSON string interface. So, for example, there might be a function implemented by the back-end;

Code:
string getMap()


If the string is empty, the back-end does not support mapping. otherwise it returns the known map as a JSON string.

To take a concrete example, this map is drawn from this string:

Image

Code:
{"places":
        [{"id":1,"name":"On The Path","gx":2,"gy":1,"exits":[12,15,2,5,11]},
        {"id":5,"name":"Rank Forest","gx":1,"gy":2,"exits":[11,1,2,3,6,8,7]},
        {"id":7,"name":"Forest Clearing","gx":0,"gy":2,"exits":[11,5,6,8,10,9]},
        {"id":11,"name":"Rank Forest","gx":0,"gy":0,"exits":[24,13,12,1,7,9,27]},
        {"id":12,"name":"On The Path","gx":2,"gy":0,"exits":[13,14,15,1,11,24]}]}


To put something like this in XVAN, the game code would "export" some properties of a given room such as exits, name and whether it has been explored, then some "C" glue code would make the string and return it.

That's the sort of thing i had in mind, anyhow.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon Jun 05, 2017 2:32 pm 
Offline

Joined: Sun Mar 10, 2013 4:17 pm
Posts: 70
Location: Flatheadia, G.U.E
I'd really like to see a standard library for XVAN, as well as an update to the interpreter (so the file doesn't have to be called "out.dat.")


Top
 Profile Send private message  
Reply with quote  
PostPosted: Tue Jun 06, 2017 2:10 pm 
Offline

Joined: Wed Aug 26, 2015 11:18 am
Posts: 87
Location: The Netherlands
jkj yuio and Flathead, thanks for your feedback. I'll start working on the library and as soon as I start working on the xvan sources, I'll try to implement the argc/argv mechanism to read filenames and options from the command line.

First step will be to create a sample library file. It won't compile in the current version but is merely to check if I'm in the right direction. Currently, I have the following assumptions for the library:

  1. The library file contains XVAN source code, human readable. It is not a compiled binary that is read by the interpreter.
  2. The library looks like the vocabulary file, but it also contains common descriptions, common flags, common attributes and common triggers. For example, the verb take will check for flag takable==1, so if the verb is in the library, the flag should be as well.
  3. From a version control point of view, I would not encourage authors to change the library file. This means they must have the possibility to redefine what's in the library in their story file. E.g. if an author needs a different implementation of "get", he would not hack the library file, but he would define a verb "get" in his story file and the compiler would know to compile that code and not the library code. Maybe calculate a checksum on the library and check it at compile time and throw a warning if it doesn't match or would that be too strict?

I'm thinking about abandoning the vocabulary file at some point and replace it by the possibility for the author to include other files.

The Cloak of Darkness story file would then start something like this:

Code:
TITLE   "Cloak of Darkness"
VERSION "1.0"

$LIBRARY main_lib.xvn

# following includes may also be replaced by the actual file content

$INCLUDE my_verbs.xvn
$INCLUDE my_enhanced_vocabulary.xvn   # extra words that I need and that are not in the library
$INCLUDE my_common_descrs.xvn
$INCLUDE my_common_flags.xvn
$INCLUDE my_common_attribs.xvn
$INCLUDE my_common_triggers.xvn

#===========================     
# Locations part
#===========================

#-------------------------------------------------------------------------------
LOCATION l_foyer
 DESCRIPTIONS
   d_sys        "the foyer hall", "the foyer", "a spacious hall", "the opera house"

   d_entr_long  "You are standing in a spacious hall, splendidly decorated in red /
                 and gold, with glittering chandeliers overhead. The entrance from /
                 the street is to the north, and there are doorways south and west."

   d_entr_short "Foyer of the Opera House"

   d_no_go      "You've only just arrived, and besides, the wheather outside seems /
                 to be getting worse..."

 EXITS
  south -> l_bar
  w     -> l_cloakroom

 FLAGS
   f_lit = 1

 TRIGGERS
   "look"              -> t_look
   "examine [l_foyer]" -> t_look
   "go north"          -> t_no_go
   "go to north"       -> t_no_go

   t_no_go
     printcr(d_no_go)
     disagree()

END_LOC
#-------------------------------------------------------------------------------
etc
etc


Would this make things easier?


Top
 Profile Send private message  
Reply with quote  
PostPosted: Tue Jun 06, 2017 2:49 pm 
Offline
User avatar

Joined: Sat Jun 25, 2016 12:13 pm
Posts: 152
definitely the way to go. I think the demo games will be a lot smaller and easier for people to understand the implementations.

if its any use, here are my own changes to xvan;

xc/init.c
Code:

@@ -26,13 +26,12 @@
 /*************************/
 /* Function declarations */
 /*************************/
 
 int32_t ExitMsg(void);
 int32_t PreDefs(void);
-int32_t main(void);
 
 
 /************************/
 /* Function definitions */
 /************************/
 
@@ -122,13 +121,14 @@
   if (!GetTriggerId("default", &id, COMMON_TRIGGERS, 1))
     return(ERROR);
 
   return(OK);
 }
 
-int32_t main() {
+int main(int argc, char** argv)
+{
   char      storyfile[MAX_ID_LENGTH+1] = "";
   char      vocabfile[MAX_ID_LENGTH+1] = "";
   int32_t   storyfile_linenum = 1;
   int32_t   err = 0;       /* No errors yet. */
   storyInfo story_info;
 
@@ -152,18 +152,39 @@
   printf("                           max  %d common triggers\n", LAST_COMMON_TRIGGER_ID-FIRST_COMMON_TRIGGER_ID+1);
   printf("                           max  %d local triggers\n", LAST_LOCAL_TRIGGER_ID-FIRST_LOCAL_TRIGGER_ID+1);
   printf("                           max %d words\n", LAST_WORD_ID-FIRST_WORD_ID+1);
   printf("                           max %d verbs\n", LAST_VERB_ID-FIRST_VERB_ID+1);
   printf("                           max  %d timers\n", LAST_TIMER_ID-FIRST_TIMER_ID+1);
 
+  int i;
+  storyfile[0] = 0;
+  for (i = 1; i < argc; ++i)
+  {
+      if (argv[i][0] == '-')
+      {
+          ErrHdr();
+          printf("unrecognised option '%s'\n", argv[i]);
+          ExitMsg();
+          return(ERROR);         
+      }
+      else
+      {
+          strncpy(storyfile, argv[i], sizeof(storyfile));
+          storyfile[sizeof(storyfile)-1] = 0; // ensure termination
+      }
+  }
 
-  /* Get storyfile name. */
-  printf("\n\nStoryfile: ");
-  scanf("%19s", storyfile);
-  storyfile[MAX_ID_LENGTH] = '\0';
-  printf("\n");
+  // if not provided, ask it.
+  if (!storyfile[0])
+  {
+      /* Get storyfile name. */
+      printf("\n\nStoryfile: ");
+      scanf("%19s", storyfile);
+      storyfile[MAX_ID_LENGTH] = '\0';
+      printf("\n");
+  }
 
   /* open the storyfile */
   strncpy(current_filename, storyfile, MAX_ID_LENGTH+1);
   if ((source_file = fopen(storyfile, "r")) == NULL) {
     ErrHdr();
     printf("Error opening %s\n", storyfile);
@@ -284,10 +305,10 @@
   /* release malloc'ed space */
   FreeTables();
 
   if (err)
     printf("\nCompilation aborted...\n");
   printf("%d lines compiled.\n", total_lines);
-  ExitMsg();
+  //ExitMsg();
 
   return(OK);
 }


xvan/Input.c

Code:
  char *line_buf;
 {
   int     gotline;
   int     len;
   event_t ev;
 
-  glk_request_line_event(mainwin, line_buf, 255, 0);
+  glk_request_line_event(mainwin, line_buf, INPUT_LINE_LEN, 0);
   gotline = 0;
 
   while (!gotline) {
     glk_select(&ev);
     switch (ev.type) {
       case evtype_LineInput:



Top
 Profile Send private message  
Reply with quote  
PostPosted: Tue Jun 06, 2017 3:19 pm 
Offline

Joined: Wed Aug 26, 2015 11:18 am
Posts: 87
Location: The Netherlands
Sorry for my ignorance but can you explain what the tekst like @@ -122,13 +121,14 @@ means?

You took a shot at the command line parameters. I'm thinkning about implementing max 3 parameters: inputfilename -<option charstring> outputfilename. When no inputfilename is given, ask for it and when no outputfilename is given it will be out.dat.

Regarding the input.c, you told me in the other forum as well. I did look into it but forgot to follow up. The INPUT_LINE_LEN definition is 80 chars. I saw in Zarf's model.c example for glk that he called the function with 255 as parameter. That's the reason I copied the 255 as I was afraid the function could return more than 80 characters.

Next thing, I will post the library example as soon as I finish it.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Tue Jun 06, 2017 4:17 pm 
Offline
User avatar

Joined: Sat Jun 25, 2016 12:13 pm
Posts: 152
Hi Marnix,

Sorry those weird @@ things are because this is a patch diff. I just copied and pasted it from my editor. If you ignore those bits and just look at lines marked + and -, those show the changes i made.

Indeed, my argc, argv was a quick change to add just one thing, but i was hoping it would indicate the sort of thing i mean, not necessarily to be taken as an actual code change suggestion.

regarding the INPUT_LINE_LEN, if i pass in 255 the request_line_even function can fill up to 255 although the buffer is 80. On my system it crashes if i don't make this INPUT_LINE_LEN.

good luck with the lib. I think it's the way to go!.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Tue Aug 08, 2017 1:44 pm 
Offline

Joined: Wed Aug 26, 2015 11:18 am
Posts: 87
Location: The Netherlands
I made a new version with some changes.

Command line:
The compiler and interpreter now accept inputfile and outputfile from the command line.
Code:
Windows:
compiler -i <inputfile> -o <outputfile>
interpreter <storyfile>

Code:
Linux:
./Compiler -i <inputfile> -o <outputfile>
./Interpreter <storyfile>

If you omit one or both filenames they will be prompted for.

Unfortunately, the Glk libraries don't support argc/argv, so the Glk version of the interpreter still requires the storyfile to be named out.dat.

Insert
The compiler now understands 'insert <filename>'. It will then open the file <filename> and continue compiling from this file. After an EOF it will switch back to the original file. Insert can go one level deep. It is implemented at the file I/O level so the compiler logic is unaware of it. Theoretically, you can change one word in the source code by an insert statement with a file with that one word in it.
It's not a full library yet, because for a library I would want to be able to redefine things from the library in the source without getting a 'duplicate definition' error. I'm still working on that but for now you can move big chunks of text from the source file into separate files.

I haven't refactored the sample stories yet, I must finish the library thing first.

The current work is in version 2.2 that can be found here

As always, feedback is highly appreciated.


Top
 Profile Send private message  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group