conversation logic/dialog editor

32 views
Skip to first unread message

dczanik

unread,
Apr 20, 2012, 6:49:51 PM4/20/12
to project...@googlegroups.com
Hey guys,

I think I remember Death 999 mentioning something about creating a conversation logic interpreter for UQM/Project 6014.  Something that would allow for the writing of non-linear dialog and make it easy for even non-programmers to use.  Has this been implemented?  

Otherwise, something like Chat mapper might be helpful to both the writers & programmers.  

Chat Mapper is windows only, so Linux/Mac users seem to have no solution.  

Cedric Horner

unread,
Apr 20, 2012, 6:57:10 PM4/20/12
to project...@googlegroups.com
Yeah Death, hurry up and make this! :)

Man it would be useful

--
You received this message because you are subscribed to the Google Groups "project6014-dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/project6014-dev/-/6opM-NExbTsJ.
To post to this group, send email to project...@googlegroups.com.
To unsubscribe from this group, send email to project6014-d...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/project6014-dev?hl=en.

drac...@aim.com

unread,
Apr 20, 2012, 7:20:37 PM4/20/12
to project...@googlegroups.com
Uurgh.

It's close, but I've been so distracted with little things like buying a house. Do you have the global state get and set functions ready? That'll help me get it a lot closer.

Luke

Dan Trivates

unread,
Apr 20, 2012, 11:16:12 PM4/20/12
to project...@googlegroups.com
You too, Luke? We take possession on May 26.

Edmund Horner

unread,
Apr 24, 2012, 2:43:43 AM4/24/12
to project...@googlegroups.com
I added two functions, see
http://code.google.com/p/project6014/source/detail?r=2313.

These ones only work on BYTE values so far. You can look at the changes
in melnorme.c and chmmrc.c too see how they work.

More accessors can be added as needed but I'd like to see the
conversation thing in action using these.

Bafla

unread,
Apr 24, 2012, 2:50:20 AM4/24/12
to project6014-dev
Can, at the very least, we get an example of a dialog file
explaining the different features? there was one a while back ( don't
remember who invented it)
that way we can start writing dialog independently from code.

Edmund Horner

unread,
Apr 24, 2012, 3:07:10 AM4/24/12
to project...@googlegroups.com
The dialog language is documented here
http://code.google.com/p/project6014/wiki/DialogLanguage. Though Death
999 may have tweaked it a bit while implementing it.

There are a few examples there, but we probably need an expert to
translate a first conversation so the rest of us know how it'll connect
with the game.

Damon Czanik

unread,
Apr 24, 2012, 11:48:07 AM4/24/12
to project...@googlegroups.com
Okay. So this is implemented now then? Or at least some rudimentary form of it at least?

--
You received this message because you are subscribed to the Google Groups "project6014-dev" group.
To post to this group, send email to project6014-dev@googlegroups.com.
To unsubscribe from this group, send email to project6014-dev+unsubscribe@googlegroups.com.

Joris van de Donk

unread,
Apr 24, 2012, 4:45:45 PM4/24/12
to project...@googlegroups.com
I don't think it's implemented yet, but I'm writing a JavaScript interpreter for it. So far, I've parsed the structure completely (with the exception of conditions and consequences; I'm going to do some nasty eval magic for those, so I'm storing them as strings now). Will get to do some of the logic later.

So far, I have the following comments, mostly based around my implementation efforts and my attempts at reading/understanding some of the more advanced examples:

- There is some annoying 'obscure logic', for example with the way that certain conditions for options are implied based on previous options with the same name (in the docs:"option hi >said_hi // implicitly =SLUGS_DEFEATED due to also being a 'hi' option.").. I'd strongly advise removing that little feature...
- Same goes for the various scopes. Although I like the scoping, I think it's *way* too obscure and unintuitive. If we have to tell everyone to read the docs intently before writing dialogues, nobody will write them or the dialogues will be buggy as hell.
- Remove the SQRT and POW functions. Put them back into the specs once we need them. I don't think we need them.
- Make everything an integer, and make the "!" condition evaluate to "VALUE==0" and the "=" condition evaluate to "VALUE==1" where VALUE is the body after the ! or = sign. Convert 'true' to '1' and 'false' to '0', so "=Reputation>50" evaluates to "(Reputation>50)==1". The docs vaguely refer to booleans and/or integers, and there's that "#" sign that crops up at places but was never properly introduced (I assume it meant "parseInt()" or something?).
- Remove the + and - operators (set/unset). Replace them with a single 'set' operator ("$"?). Want to set a flag? $hasbomb=1. Unset a flag? $hasbomb=0. Toggle flags with something like $hasbomb=!hasbomb. Not very readable, but more understandable.
- The ">" and "<" compounds should be removed, since they require reading of the documentation. I understand why they were added, but they just make it harder for the dialogue writers to understand existing dialogue.
- Can consequences be placed at the end of a 'block'? That way, we get something like ".fight +Rep=-1", rather than "option =HAVE_SLUG_REPELLENT +Rep=-1"

That's it so far. I'm sure some of my suggestions may be slightly idiotic to people that truly understand the dialogue language, so ignore those. :)

-Joris

To post to this group, send email to project...@googlegroups.com.
To unsubscribe from this group, send email to project6014-d...@googlegroups.com.

drac...@aim.com

unread,
Apr 24, 2012, 9:05:37 PM4/24/12
to project...@googlegroups.com
Okay, status update.

For the dialog writers, (Ariel?) I'd like a little feedback on what you can handle. See below in the interlinear quotes.

Spurred by the recent conversations, I've gotten back to it. I'm almost to the compile and test stage. The blocking issue was a big refactoring from my structures containing strings to their containing indices into a string table.

The other blocking issue was my having to understand better how the UQM conversation code works. The only documentation is variable and function names, and the header files unhelpfully define superfluous macros that indirect the other calls in not very helpful ways. I think I've got a handle on the relevant parts of it now, so I may get it together soon.

Anyway, rewriting the other language in the event of changes will be comparatively easy once I've got it hooked up. Not exactly easy, but it's all stuff that I know how it works.

So, anyway, Joris' email was very interesting, if only from the in-progress alternate implementation, in JS no less!

> (with the exception of conditions and consequences; I'm going to do some nasty eval magic for those, so I'm storing them as strings now

I store them as strings too, and evaluate via string surgery. That was pretty painful in C, what with manual memory management and having to figure out the lifetime of every intermediate string.

On Apr 24, 2012, at 4:45 PM, Joris van de Donk wrote:


> So far, I have the following comments, mostly based around my implementation efforts and my attempts at reading/understanding some of the more advanced examples:
>
> - There is some annoying 'obscure logic', for example with the way that certain conditions for options are implied based on previous options with the same name (in the docs:"option hi >said_hi // implicitly =SLUGS_DEFEATED due to also being a 'hi' option.").. I'd strongly advise removing that little feature...

I do not think this is obscure at all. Go down the list, use the first that fits. Think of it as chained 'else if' !
Don't forget, names are optional on options. You can leave them all independent.

- > Do other dialog writers think this idea is complicated?

> - Same goes for the various scopes. Although I like the scoping, I think it's *way* too obscure and unintuitive. If we have to tell everyone to read the docs intently before writing dialogues, nobody will write them or the dialogues will be buggy as hell.

All three are utterly vital. Maybe the syntax can change, but I think it's pretty intuitive.

The idea is just that you need to keep track of some things only for the length of the conversation... some things have only to do with this race... and some things are global to the game...
and you indicate which is which by letting something that's the first sort have a lowercase name... the second you use a MixedCase name, and the last has an ALL_CAPS name.

- > Do other dialog writers think this is complicated?

> - Remove the SQRT and POW functions. Put them back into the specs once we need them. I don't think we need them.

It's trivial to ignore them if you don't need them, and they're already implemented in C.

- > Do other dialog writers think this is a major distraction?

> - Make everything an integer, and make the "!" condition evaluate to "VALUE==0" and the "=" condition evaluate to "VALUE==1" where VALUE is the body after the ! or = sign. Convert 'true' to '1' and 'false' to '0', so "=Reputation>50" evaluates to "(Reputation>50)==1". The docs vaguely refer to booleans and/or integers, and there's that "#" sign that crops up at places but was never properly introduced (I assume it meant "parseInt()" or something?).

I already got rid of the # symbol and believe I changed the documentation to reflect this change, a long time ago. Everything is now, as you say, int typed.

> - Remove the + and - operators (set/unset). Replace them with a single 'set' operator ("$"?). Want to set a flag? $hasbomb=1. Unset a flag? $hasbomb=0. Toggle flags with something like $hasbomb=!hasbomb. Not very readable, but more understandable.

maaaybe. Readability is, IMO, far more important than keeping the symbol list under control. There are only 5 special symbols anyway, and they all have obvious mnemonics: + - < > ~

- > Do other dialog writers think this would be an improvement?

> - The ">" and "<" compounds should be removed, since they require reading of the documentation. I understand why they were added, but they just make it harder for the dialogue writers to understand existing dialogue.

I really doubt it. If you need to write it twice (check and set), it introduces opportunities for insidious one character off errors. Also, it's an atomic operation - a state transition. It's such a common idiom that breaking it up seems perverse.

- > Do other dialog writers think this would be an improvement?

> - Can consequences be placed at the end of a 'block'? That way, we get something like ".fight +Rep=-1", rather than "option =HAVE_SLUG_REPELLENT +Rep=-1"

Maybe that would work, but it gets in the way of the '>', which is a good thing to have as described above.

> That's it so far. I'm sure some of my suggestions may be slightly idiotic to people that truly understand the dialogue language, so ignore those. :)

Not idiotic for sure! I've probably written way more in it than you, though, since I have a very similar language implemented in java already.


Luke

drac...@aim.com

unread,
Apr 24, 2012, 10:27:11 PM4/24/12
to project...@googlegroups.com

On Apr 24, 2012, at 2:50 AM, Bafla wrote:

> Can, at the very least, we get an example of a dialog file
> explaining the different features? there was one a while back ( don't
> remember who invented it)
> that way we can start writing dialog independently from code.

There is an example at the bottom of the wiki page, http://code.google.com/p/project6014/wiki/DialogLanguage

I just now beefed up the comments on the example dialog a lot. Maybe that will help.

I plan on converting the Pkunk dialog to this language, and when I do one can look through that to see how it's organized.

Luke

drac...@aim.com

unread,
Apr 24, 2012, 10:47:53 PM4/24/12
to project...@googlegroups.com
I couldn't do an svn update because it skipped 'trunk'.

Any idea how I can get it not to do that? Using mac 10.6.8, the svn that comes up in terminal without special effort.

Luke

Edmund Horner

unread,
Apr 24, 2012, 11:39:07 PM4/24/12
to project...@googlegroups.com, drac...@aim.com
You can try just updating the "sc2" subdirectory (which contains src and
content).

If that doesn't work, tell me what the name of your top level working
copy is, and what you ran to try to update it.

Ariel Azia

unread,
Apr 25, 2012, 2:38:42 AM4/25/12
to project...@googlegroups.com
The syntax seems reasonable, but I really would like an example.
Maybe the slugs example revisited?

once I have an example, I will try to re-write the Shofixti dialog and run it against you guys
to see I got the syntax correctly


Joris van de Donk

unread,
Apr 26, 2012, 3:37:12 PM4/26/12
to project...@googlegroups.com
The JS-Dialogue project can be found at  http://mooses.nl/uqm/wip/js-dialogue/ 
Currently, it only parses and displays dialogue files. You can't run dialogues yet, but the tool should allow you guys to understand the dialogue language (or the dialogue example :P) a bit better.
As usual: tested on Chrome only; may contain bugs; MIT-licensed.

-Joris

Joris van de Donk

unread,
Apr 26, 2012, 3:57:39 PM4/26/12
to project...@googlegroups.com
Heh. I'm fairly certain that in the example on the wiki page, "<try_shoot" should be replaced with ">try_shoot". It's temporarily scoped, and try_shoot is never set, so that dialogue option won't ever be shown. :)
Unless I'm interpreting the dialogue script wrong, of course.

-Joris

drac...@aim.com

unread,
Apr 26, 2012, 4:19:41 PM4/26/12
to project...@googlegroups.com
You were correct!

I'm making a list of things to include in a error-catching utility. That will be one of them.

Anyway, since I couldn't get the svn update to work, I'm just re-fetching the whole thing. Then it's on to whittling away at the inevitable compilation errors, and then to testing the functionality.

By the way, for storing int data... does anyone know why this wouldn't work?

Use a
GHashTable *transientState;
initialize it...

to store an int newval keyed to string *name...
g_hash_table_insert(transientState, name, newval);

to recover it,
(int)(g_hash_table_lookup(transientState, name))

Does that have any glaring flaws?

Of course we'd need to write (de)serialization functions.

Luke

drac...@aim.com

unread,
Apr 26, 2012, 4:32:36 PM4/26/12
to project...@googlegroups.com
On Apr 26, 2012, at 4:19 PM, drac...@aim.com wrote:

Use a
GHashTable *transientState;

Oh, right - this would be a longer-term state, not transient. I just copied it over...

Luke

Joris van de Donk

unread,
Apr 28, 2012, 3:42:58 PM4/28/12
to project...@googlegroups.com
Would it perhaps be possible to change the specs so that flags and node names can only contain A-Z, a-z, 0-9 and the underscore (_)? It would make validation a lot easier (don't have to keep a table of special characters) and prevents potential dialogue corruption whenever additional special characters are introduced in the future.

-Joris

drac...@aim.com

unread,
Apr 28, 2012, 7:08:06 PM4/28/12
to project...@googlegroups.com
Sure.
I would add parentheses to the character whitelist, as I have committed to their NOT being metacharacters.

I have a crazy busy weekend, but I will definitely be hard at work compiling and fixing on monday. Also, starting tuesday, I will have around 3 total hours of train ride to/from work every day. That will help a lot.

Luke

Joris van de Donk

unread,
Apr 29, 2012, 5:33:41 PM4/29/12
to project...@googlegroups.com
I switched my own implementation around a bit and I'm now using a list of special characters to determine if something is a special character. I also made things even easier on my end to parse if by removing numbers (0-9) from flag/node names and always treating them as actual numbers; that way, parsing becomes rather trivial. I'm sure that we'll have to 'synchronize' our implementations later, but I've structured my parser in such a way that I can easily switch things around later. Your implementation of the language should be leading, especially since I think that it's way harder to implement it in C on an existing codebase than it is to implement it in JavaScript without any existing codebase.

Either way, I've updated my parser at http://mooses.nl/uqm/wip/js-dialogue/ 
It's now possible to play through an actual conversation via the Developer Console (ctrl-shift-j in Google Chrome, then go to 'Console' tab; Firebug also works with the Console, and Opera also has a console somewhere).
Load the example, parse it, then check the console for details.

Try entering the following in the developer console (line-by-line; don't paste it all in at once) after you've loaded the example dialog:
startConversation(); //Start the conversation
dO(0); //Select option #0
dO(1); //Say goodbye
SCOPE.global.HAVE_SLUG_REPELLENT = 1; //Give ourselves some slug repellent :D
startConversation(); //Let's talk to them again
dO(1); //Introduce ourselves
dO(0); //Ask the computer if we have some of that sweet repellent.
dO(0); //Give the repellent to the aliens.
dO(1); //Say goodbye
startConversation(); //Let's talk to these guys again.
dO(1); //Say hi again
//Great; they're happy now! :D
dO(1); //Say goodbye...

Also, 3 hours train ride? Ouch.

-Joris

Joris van de Donk

unread,
May 4, 2012, 4:41:22 PM5/4/12
to project...@googlegroups.com
I've updated the dialogue tool. It now includes a neat graphical representation of a conversation.
Dark circles inside nodes represent options that lead back to the same node. White circles represent nodes that lead to some other node. Follow the lines to see where it goes. An octagon at the edge of a node represents a 'target' of a GOTO.
Need to figure out how to automatically generate a proper layout. My current layouting scheme is kind of crap.

As usual, may not work properly in IE. See attachment for what it *should* look like after some manual repositioning of nodes.

-Joris
graphicalrepresentation.png

Joris van de Donk

unread,
May 6, 2012, 12:45:31 PM5/6/12
to project...@googlegroups.com
Updated it again. It now contains a graphical conversation simulator, as well as a scope viewer/editor.

-Joris

Damon Czanik

unread,
May 6, 2012, 1:22:49 PM5/6/12
to project...@googlegroups.com
Praise Joris!

This is awesome man! The user friendliness of the program has jumped through the roof on this one.

As a suggestion, since some of the writers have little or no programming experience, it may be a little confusing to them still.
I think we're at (or close) to a version that the writers can try this, and give suggestions on.
Perhaps some sections of example code they can click to insert into the editor, like snippets from the example? 

IE. Clicking on: Talk option might bring up:

option hi
Insert your text here
.main

Or create more of a focus on content creation from the graphical viewer (like DIA/Visio). I think you had mentioned you had this planned.
You already have great ideas on how this should be implemented (as seen in UQM-ConversationTool), so I trust you'll make this even better.

I can't wait to see this implemented into the game engine. Very cool stuff.
churchsign.jpg

drac...@aim.com

unread,
May 6, 2012, 6:56:44 PM5/6/12
to project...@googlegroups.com
On May 6, 2012, at 1:22 PM, Damon Czanik wrote:

I can't wait to see this implemented into the game engine. Very cool stuff.

Yeah... on that...

I'm waiting on someone who knows about the build system to tell me how to get glib into uqm. I'm stumped.

Luke

dczanik

unread,
May 7, 2012, 7:01:44 PM5/7/12
to project...@googlegroups.com
Nobody can help Luke with getting glib into uqm?? Hello?

I've been going over the dialog stuff using Joris' tool.   

I do have some question:
How would I handle IF type statements with AND or OR type logic.

Example:
If  (CHMMR=fixed), OR (CHMMR=friendly)
{
  Do This:
}

If (have SunDevice) AND (Ultron=Fixed)
{
   Do This:
}

Also,
Would this also include stuff like audio file info?
What about multiple languages? How would that be implemented? Just copied/pasted into new files?

drac...@aim.com

unread,
May 7, 2012, 9:38:11 PM5/7/12
to project...@googlegroups.com

On May 7, 2012, at 7:01 PM, dczanik wrote:

> How would I handle IF type statements with AND or OR type logic.
>
> Example:
> If (CHMMR=fixed), OR (CHMMR=friendly)
> {
> Do This:
> }
>
> If (have SunDevice) AND (Ultron=Fixed)
> {
> Do This:
> }

The AND is easy - just list the conditions one after another separated by spaces, like this

> option =HAVE_SUN_DEVICE =ULTRON_FIXED


The OR is a bit less easy. The reason is, I found that in general, OR didn't actually come up much in actual conversations. Normally, the two branches of an OR would provoke slightly different responses, so I didn't actually want to treat them as one.

If you insist on using OR, though, you have three options.

strategy 1: use arithmetic. 0 is false, anything else is true, and if you just set a flag to 'true' it becomes 1. So, if these are plain flags, then if you add them, either one being 1 will make their sum nonzero.

> option =ChmmrFixed+ChmmrFriendly

If these flags are numeric and strictly positive, it still works. If they are set to potentially negative numbers, it gets a bit more complicated. Use square brackets to isolate equations or inequalities. These evaluate to 1 if true or 0 if false.
So, 'ChmmrFixed OR ChmmrFriendliness over 5' would be

> option =ChmmrFixed+[ChmmrFriendliness>5]



strategy 2: use two named items for the two branches of the OR, and use a text item to contain the result. This makes sense if the algebra on the above case gets really out of hand or is confusing for other reasons.

e.g.
> option =ChmmrFixed
> [friendlyHi]
> .main
>
> option =ChmmrFriendly
> [friendlyHi]
> .main
>
> text friendlyHi
> Hi!!!!


strategy 3: set a flag that is set when either of those conditions is met, then use that. This involves more global changes so I'm not going to give an example.


> Also,
> Would this also include stuff like audio file info?

That was one of the things that slowed me down a lot. I rebuilt it so that this does not interfere with the functioning of the existing audio system.
The audio mappings can be included in the same way they are now, with a separate file.

Eventually, we may (or may not) want to do this via display directives. I think that would be a reasonable step to take only if all the dialog is handled by this system. It would involve going in and mucking around with things outside the system itself.

> What about multiple languages? How would that be implemented? Just copied/pasted into new files?

The simplest to code is to generate an equivalent, translated conversation file with the same logic in it.
An alternative is to replace the string table after the conversation file is loaded, but then I'd need to figure out how to do that.

Luke

drac...@aim.com

unread,
May 8, 2012, 6:18:47 AM5/8/12
to project...@googlegroups.com
My second example was a bit off... I omitted the name 'GoodHi' (which was needed to keep from showing both if both conditions were met), and I left some things out of the text item.

Fixed version below.

On May 7, 2012, at 9:38 PM, drac...@aim.com wrote:

option GoodHi =ChmmrFixed
[friendlyHi]
.main

option GoodHi =ChmmrFriendly
[friendlyHi]
.main

text friendlyHi
Howdy there, mechanoids!
GREETINGS, CAPTAIN.
.

Damon Czanik

unread,
May 8, 2012, 1:16:57 PM5/8/12
to project...@googlegroups.com
Cool. I've got it now.

Regarding audio. I think we were leaning towards using the SMIL format which also deals with handling audio.  If there was some way to trigger a .SMIL file that would help out.  (Whenever .SMIL gets implemented)... This could also allow us to handle different situations like in UQM when you first meet Hayes.  Loading a different .SMIL file would allow me to add things like some static and flashing lights when you first meet Hayes in UQM.

Example:
greeting =stationpower<1  =radioactives<1 {exec hayes_lowpower.smil}
Attention unidentified vessel. This is Commander Hayes of the Slave Planet Earth
.helphayes

Not sure if that's the right logic, but you played the game, and know what I'm talking about :)
That would allow us to get around situations like the (lack of) glowing/color-cycling issues (for Slylandro, Mad Orz, etc.), and we could even handle lip syncing events too.  
Other things we could do: 
  show damage, explosions, exploding consoles, etc. if a base is under attack, 
  remove/add slave shields in the background, 
  change backgrounds if it's day/night, etc.

But, baby steps... :)  We got to get the dialog system in place first. ;-)  We'll need to get glib up for you.  Have you tried the glib forums? Perhaps they can help.


Luke

--
You received this message because you are subscribed to the Google Groups "project6014-dev" group.

Jaakko Seppälä

unread,
May 9, 2012, 3:23:44 AM5/9/12
to project...@googlegroups.com
Hi, Luke.

Sorry to say that I don't know about the glib stuff :( Maybe Benjamin
or Edmund are wiser than me in this regard.

Jaakko

drac...@aim.com

unread,
May 9, 2012, 6:32:28 AM5/9/12
to project...@googlegroups.com
Hi,

I don't think it's so much glib in specific as just getting libraries to be recognized by the build system. Once it is, then we can think about the errors glib itself introduces, if any still occur. It could have been due to some mistake in my command-line compilation attempt due to not specifying that it should use a modern version of the language version or something that seems like it ought to be automatic like that.

Luke

Jaakko Seppälä

unread,
May 9, 2012, 8:11:39 AM5/9/12
to project...@googlegroups.com
So, you're on OS X, Luke?

I haven't had to mess around with the build a lot, but I've done some
edits to build/unix/build.config.
Perhaps that's the right one to edit.

I found there's:
# Find Frameworks and copy them into the application.
echo "Copying dependancy Frameworks..." >&2
HEADERS="Ogg/Ogg.h SDL/SDL.h SDL_image/SDL_image.h Vorbis/vorbisfile.h"

in one place of the build.config file. Perhaps adding glib's .h files
there would do the trick?

Jaakko

drac...@aim.com

unread,
May 9, 2012, 10:29:05 AM5/9/12
to project...@googlegroups.com

On May 9, 2012, at 8:11 AM, Jaakko Seppälä wrote:

> So, you're on OS X, Luke?
>
> I haven't had to mess around with the build a lot, but I've done some
> edits to build/unix/build.config.
> Perhaps that's the right one to edit.
>
> I found there's:
> # Find Frameworks and copy them into the application.
> echo "Copying dependancy Frameworks..." >&2
> HEADERS="Ogg/Ogg.h SDL/SDL.h SDL_image/SDL_image.h Vorbis/vorbisfile.h"
>
> in one place of the build.config file. Perhaps adding glib's .h files
> there would do the trick?
>
> Jaakko


Yup, OSX.

That lists individual header files, and glib has tons. I need a place to add a -I option to gcc so it just knows where to find them, not the location for a specific header.

Moreover, those you listed aren't simply header files - they're frameworks. There's a level of abstraction around them that isn't present for glib. There is no file, for instance, that has a path containing "Ogg/Ogg.h": Ogg.h is in Ogg.framework/Versions/A/Headers, and there are symlinks so it's accessible via Ogg.framework/Headers and Ogg.framework/Versions/Current/Headers... but nowhere is it Ogg/Ogg.h.

It was enough to make me consider implementing the parts I need locally. UQM contains a list.c and list.h that I don't understand because it's so heavy on C preprocessor stuff I don't have experience with, but I could try to figure that out. Or I could just make one from scratch (I've made linked lists before). If we can also get a halfway decent hashtable implementation, we could do without glib. Hashtables look noticeably trickier than lists.

Luke

Jaakko Seppälä

unread,
May 10, 2012, 3:17:46 AM5/10/12
to project...@googlegroups.com
Ah, I feared it wouldn't be that simple :(
Those list.c & .h files indeed look quite tricky.

I'm at the end of my wits here. Actually, at work I've a similar
situation - I needed to add a external library of tens of header files
to my project. After several hours of messing about, I just added each
individual .h file to the makefile script :-p. Not elegant, but
there's so many more important things to finish before the deadline...
But I reckon that's not an option for you if glib has shit-tons of headers.

J

Edmund Horner

unread,
May 10, 2012, 3:46:42 AM5/10/12
to project...@googlegroups.com
I have managed to build with glib on Linux if that helps. See the diffs in:

http://code.google.com/p/project6014/source/detail?r=2316

Notice a) that I simply include <glib.h> (not glib-2.0/glib.h or
anything else funny).
b) The changes to the build scripts.

Other changes may be necessary for other OSes of course. But I think
this is a start.

Disclaimer: I still have approximately no idea how the build system works.


On 10/05/12 19:17, Jaakko Sepp�l� wrote:
> Ah, I feared it wouldn't be that simple :(
> Those list.c& .h files indeed look quite tricky.
>
> I'm at the end of my wits here. Actually, at work I've a similar
> situation - I needed to add a external library of tens of header files
> to my project. After several hours of messing about, I just added each
> individual .h file to the makefile script :-p. Not elegant, but
> there's so many more important things to finish before the deadline...
> But I reckon that's not an option for you if glib has shit-tons of headers.
>
> J
>
> On Wed, May 9, 2012 at 5:29 PM,<drac...@aim.com> wrote:

benjam...@free.fr

unread,
May 10, 2012, 5:29:20 AM5/10/12
to project...@googlegroups.com
Let me second that, along with a few seconds of despair about how little free time I have these days.

B.

----- Mail original -----
De: "Edmund Horner" <ejr...@gmail.com>
À: project...@googlegroups.com
Envoyé: Jeudi 10 Mai 2012 09:46:42
Objet: Re: conversation logic/dialog editor

Damon Czanik

unread,
May 10, 2012, 1:05:40 PM5/10/12
to project...@googlegroups.com
As long as you guys let us know you're still alive, that's fine with me.  We all have real life intrude on us. Be happy. Be healthy. We have others to help push forward.

Regarding the dialog.  We're going to have to switch over to the new system eventually.  Should we focus on porting to the new scripting system? It would give Death999 multiple files to test the new system.

If we are ready, this is one of those situations where many hands may make small work. Different people working on it could also provide valuable input to Joris on where we can improve the software.  

Joris? Death999? Your thoughts on this?

drac...@aim.com

unread,
May 10, 2012, 1:09:23 PM5/10/12
to project...@googlegroups.com

On May 10, 2012, at 3:46 AM, Edmund Horner wrote:

> I have managed to build with glib on Linux if that helps. See the diffs in:
>
> http://code.google.com/p/project6014/source/detail?r=2316
>
> Notice a) that I simply include <glib.h> (not glib-2.0/glib.h or anything else funny).
> b) The changes to the build scripts.

Hooray!

Shoot. I was going to link to the Hitmen for Destiny installment I was thinking of when I said that, but there's no transcript search, so never mind.

Anyway, now I'm working on my actual errors, which is nice.

Luke

drac...@aim.com

unread,
May 10, 2012, 1:11:46 PM5/10/12
to project...@googlegroups.com
On May 10, 2012, at 1:05 PM, Damon Czanik wrote:

> As long as you guys let us know you're still alive, that's fine with me. We all have real life intrude on us. Be happy. Be healthy. We have others to help push forward.
>
> Regarding the dialog. We're going to have to switch over to the new system eventually. Should we focus on porting to the new scripting system? It would give Death999 multiple files to test the new system.
>
> If we are ready, this is one of those situations where many hands may make small work. Different people working on it could also provide valuable input to Joris on where we can improve the software.
>
> Joris? Death999? Your thoughts on this?

Sounds good - you may want to run the first few files by me (and/or Joris - I expect he's fluent with it by now) for manual validation before going too far.

Luke

Damon Czanik

unread,
May 10, 2012, 1:54:28 PM5/10/12
to project...@googlegroups.com
I've been using Joris' software for writing some Mycon dialog.  I can port the Syreen stuff over.  I just don't want to port the whole game. I'll send the data to you guys to verify it works.

I do have one question:
When writing some dialog for the Mycon, and there's a "DAYS_TO_DEATH" variable that should change the greeting as it draws closer to death. I can set the variable when you first greet it, but I'd want the timer to be based off, let's say 500 days from when you start the game.

I can manually set the variable every time I want to test a conversation, but that's a bit labor intensive.  It would help if I could set some line for testing, sort of like an autoexec.bat.  Something to define it even before the greeting. A line like:

=DAYS_TO_DEATH=500  
The number could easily be changed for testing.

A separate autoexec file would allow for several common variables to be used. Otherwise, we'd have to check several files to insure we have the correct names for things common names throughout the game like artifacts.

Luke, if you think there's a better way to do this, let me know. It might save me some time.

drac...@aim.com

unread,
May 10, 2012, 11:26:07 PM5/10/12
to project...@googlegroups.com

On May 10, 2012, at 1:54 PM, Damon Czanik wrote:
I do have one question:
When writing some dialog for the Mycon, and there's a "DAYS_TO_DEATH" variable that should change the greeting as it draws closer to death. I can set the variable when you first greet it, but I'd want the timer to be based off, let's say 500 days from when you start the game.

I can manually set the variable every time I want to test a conversation, but that's a bit labor intensive.  It would help if I could set some line for testing, sort of like an autoexec.bat.  Something to define it even before the greeting. A line like:

=DAYS_TO_DEATH=500  
The number could easily be changed for testing.

Hmm. Well, I can see a kludge...

instead of

greeting =DAYS_TO_DEATH>200
blah
.myNextNode

greeting //  200 or fewer days to death
urk
.myNextNode

you delay the selection by using a text item.

greeting +DAYS_TO_DEATH=500
[greet]
.myNextNode

text greet =DAYS_TO_DEATH>200
blah
.

text greet // 200 or fewer days to death
urk
.

In the long or even medium term, we may want to have 'init' lines that go before greeting-selection. It wouldn't be challenging to add, since it's so redundant with the others - if I get the rest working, it would take under four hours to fit in, probably more like two. I wouldn't even need to define a new data type.

Lastly, I've decided that substituting text items into conditions or consequences is not just a bad idea, but it's complicated enough I don't want to implement it - not now, and unless people specifically want it (which I really doubt) not later either.

Luke

Joris van de Donk

unread,
May 11, 2012, 1:13:31 PM5/11/12
to project...@googlegroups.com
I just added syntax highlighting (via CodeMirror).
Let me know if anything doesn't seem to work correctly. 

-Joris

--

drac...@aim.com

unread,
May 15, 2012, 12:41:15 PM5/15/12
to project...@googlegroups.com
On May 10, 2012, at 3:46 AM, Edmund Horner wrote:

I have managed to build with glib on Linux if that helps.  See the diffs in:

   http://code.google.com/p/project6014/source/detail?r=2316

Looking this over...

why was this used?
memset (&gameStateMap, 0, sizeof (gameStateMap));
The documentation on GHashTable clearly says it's an opaque type, and to make one you just call 'g_hash_table_new(...)'. That initializes it properly. I'm not confident that this will even result in a legal state.

I suggest using GINT_TO_POINTER to store GINT values and POINTER_TO_GINT to recover them.

For long-term storage, we won't be able to fit this in a byte array, but we can store it separately by enumerating the map elements.
It'd look something like this, with fprintf, reportError, and readLine replaced with an appropriate access function

fprintf(file, "KEYS START\n");
char *key;
int val;
GList *flagIter = g_hash_table_get_keys(gameStateNameMap);
for (; flagIter; flagIter = flagIter->next)
{
key = flagIter->data;
val = POINTER_TO_GINT(g_hash_table_lookup(key));
fprintf(file, "%s=%d\n", key, val);
}
fprintf(file, "KEYS END\n");

and loading...

char *line = readLine(file);
char *mid;
int val;
int err;
if (strcmp(line, "KEYS START")) 
 reportError("Expected a Keys data block in save file");
g_hash_table_remove_all(gameStateNameMap); // require it to have been initialized already
while ((line = readLine(file)) && (err = strcmp(line, "KEYS END")) != 0) 
  mid = strchr(line, '=');
if (mid == NULL)
reportError("Key entry did not contain '='");
  *mid++ = '/0';
if (mid)
  val = atoi(mid); // note, 
else reportError("Save file contained a key entry ending '='");
  g_hash_table_insert(gameStateNameMap, line, GINT_TO_POINTER(val));
  free(line);
}
if (err)
  reportError("file ended in the middle of the key block!")



Does that look like it would work, with the appropriate substitutions?

Luke

Edmund Horner

unread,
May 15, 2012, 5:13:51 PM5/15/12
to project...@googlegroups.com
Comments below...

On 16 May 2012 04:41, <drac...@aim.com> wrote:
> On May 10, 2012, at 3:46 AM, Edmund Horner wrote:
>
> I have managed to build with glib on Linux if that helps.  See the diffs in:
>
>    http://code.google.com/p/project6014/source/detail?r=2316
>
>
> Looking this over...
>
> why was this used?
> memset (&gameStateMap, 0, sizeof (gameStateMap));
>
> The documentation on GHashTable clearly says it's an opaque type, and to
> make one you just call 'g_hash_table_new(...)'. That initializes it
> properly. I'm not confident that this will even result in a legal state.
>
> I suggest using GINT_TO_POINTER to store GINT values and POINTER_TO_GINT to
> recover them.

Aha! The short answer is that:

static struct map_entry gameStateMap[NUM_GAME_STATE_BITS];
static GHashTable *gameStateNameMap = NULL;

gameStateMap is a simple array of structs.
gameStateNameMap is the actual hash table.

I just want to zero the array's values (in fact just set each
stateName member to NULL). I could have used a loop but it was less
typing to do it this way. ;-) Although now that I think about it,
static data is initialised to zero anyway, so it's technically
redundant... but relying on implicit behaviour is a bit icky anyway.

The code currently seems to work, but it was written as a bit of hack
so I'm not averse to improving it.

Bear in mind I've never used glib before that change, and I added the
name map partly as an example of how to get it compiling in P6014.
(But also because I do actually need a hash table.)
Yes, once we've figured out how states will be stored (and it's likely
to be a hash table), code like the above for saving it to a file makes
sense. There's similar code for doing a debug dump of the states, but
it uses a normal loop over the array of structs, rather than the hash
table. That could be changed for starters.

Part of the problem is that the list of states is hardcoded (and each
has a certain number of bits). The way I see it, the requirements are
broadly:

1. For ease of conversation programming, defining and referencing new
states in the conversation files is desirable.
2. But some states are used in performance-critical parts of the
code, so should be accessable without doing a hash table lookup.
3. Space for storing the states in memory during runtime or in a save
file is not an issue (as it obviously was when the game was first
written). So bit packing isn't necessary.
4. We should be able to store additional states in the save file
without completely breaking save game compatibility (unlike the
current situation).
5. States that are 32-bit signed integers are probably going to be
adequate for all uses. A few places where strings are used (e.g.
captain/flagship names) can be stored separately.

I can think of a few possible ways to address item 2: store the
performance-critical states separately; do an initial lookup to find
the entry, and just reference the entry in the performance-critical
loops; store them separately, but somehow tie them into the map so
they can be used in conversations.

Anyway at this point I still think we should:

1. Focus on getting the dialogue engine incorporated and running, and
working with the admittedly-limited game state mechanism.
2. Think a bit about refactoring game states later. It shouldn't be
too hard as long as we know what it has to do.

drac...@aim.com

unread,
May 15, 2012, 5:48:54 PM5/15/12
to project...@googlegroups.com
Now I understand... (again. I understood for a while when I first read it, then forgot)... You have a map from string structs encoding locations in the bit array, and use that to get and set bytes. The bit array itself is as statically defined as before.

So... we make a second map that holds values directly and doesn't need to use predefined names, and determine at get/set time which one to use. I'll take care of the namespacing on my end, so don't worry about that.

> static GHashTable miscGameStateMap;

...
> miscGameStateMap = g_hash_table_new ( &g_str_hash, &strings_equal, &g_free, NULL);

...
> int GetGameStateByName(const char *name)
> {
> struct map_entry *e = g_hash_table_lookup(gameStateNameMap, name);
>
> if (!e)
> return POINTER_TO_GINT(g_hash_table_lookup(miscGameStateMap, name));
>
> return (int)(getGameState(e->statePos, e->statePos + e->stateLen));
> }
>
> /**
> * Sets game state, preferring to set game state in the flat byte array.
> * Values set to the flat byte array are trimmed to BYTE.
> * Other values keep full range.
> */
> void SetGameStateByName(const char *name, int val)
> {
> struct map_entry *e = g_hash_table_lookup(gameStateNameMap, name);
>
> if (!e)
> g_hash_table_insert(miscGameStateMap, name, GINT_TO_POINTER(val));
> else
> setGameState(e->statePos, e->statePos + e->stateLen, (BYTE)val);
> }


drac...@aim.com

unread,
May 16, 2012, 9:16:41 AM5/16/12
to project...@googlegroups.com
Good news and bad news.

The good news are, I got the conversation manager to compile, and I added 'init' support. To make an initializer, just use a single line entry starting 'init' followed by a regular set of conditions and consequences. The first init line to be accepted will go off before the greeting is selected.

If you want, I can make it so all init lines are tested independently (for initializing independent things independently)

This is good for things like debugging the Mycon dialog with

> init +DAYS_TO_DEATH=233


or setting up the environment in the VUX dialog,

> init +starting_apologies=Apologies




The bad news, I cant get UQM to link with glib, libintl, and zlib -

> ld: warning: in /opt/local/lib/libglib-2.0.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
> ld: warning: in /opt/local/lib/libintl.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
> ld: warning: in /opt/local/lib/libz.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
> Undefined symbols:
> (insert list of everything from glib, libintl, zlib)

so I can't test that it actually works.

sigh. Anyone know about mac compiling? I'm posting this in uqm technical discussion too.

I can send the code and the fully converted VUX and Pkunk dialogs to anyone who wants to try building and testing it on a different system.

Luke

Edmund Horner

unread,
May 24, 2012, 10:24:42 PM5/24/12
to project...@googlegroups.com
It builds on MSVC with the changes you have checked in. But it is not
used at all by the UQM code, so we haven't seen it working yet. So we
now need to do two things:

1. Get it building on Mac OS, and also on Linux (I think Linux is
fine, I just haven't tried it yet).

2. Make the VUW and Pkunk dialogs use the new engine.

Seems to me these can be done in parallel, so if you have anything
relating to the new dialogs you could check that in too. It may make
the game unrunnable but we can work on that.

If svn still doesn't work, check in using the web as before. We could
add fixing your svn repository as item 3.

drac...@aim.com

unread,
May 25, 2012, 9:52:54 AM5/25/12
to project...@googlegroups.com
I did the pkunk. That should be enough to see how everything explodes (I'm not holding out for 'if'). I can put in VUX tonight.

Luke

Jaakko Seppälä

unread,
May 30, 2012, 2:49:50 AM5/30/12
to project...@googlegroups.com
Hi, guys,

Great job on the conversation tool! That's one whopping undertaking.
I noticed that the added line
"use_library GLIB || exit 1" breaks the build down on OSX.
The build indicates that GLIB is found, but anything after that is
'not found'. (e.g. if the line is before checking if the machine has
stricmp or strcasecmp, neither is found. But if the line is after
those checks, they are found all right.)

I don't want to start messing about this bug since you guys know this
piece of code much better than me. Don't wanna destroy your hard work
with dubious 'fixes' :)
Could you take a look at it? Does this affect linux building in a
negative way at all?

Jaakko

Edmund Horner

unread,
Jun 1, 2012, 12:38:52 AM6/1/12
to project...@googlegroups.com
I moved "use_library GLIB || exit 1" to the end of that function and
it still builds on Linux.

As for why it's a problem, it could be because of the way the GLIB
variables use `pkgconfig ...` to populate themselves. I think each
use_library call appends these to CFLAGS and LDFLAGS, and maybe this
results in corrupt values for those variables in the subsequent checks
Reply all
Reply to author
Forward
0 new messages