Jump to content

Dialogue boxes on entering town not showing up? [SOLVED]


Azalea
 Share

Recommended Posts

So I have no idea how active this forum is, but since posts have been made this year and there seems to still be a small community of people who still play BoE, I guess I'll put this here. I've started designing a scenario (mainly for fun, but if there are people out there who would play it, then that's a bonus) and I'm having an issue with Stairway encounters which is baffling me.

I've essentially got two towns that are linked by a forced stairway which I've dropped on a portcullis. That works fine. However, I wanted a dialogue box to come up when the party enters the second town for the first time, like you get in Sweetgrove in VoDT. No matter what I try, it won't appear unless the special is on a space the party walks onto (when just having it in the town specials list didn't work, I tried having it so that the stairway deposits the party onto the space containing the special, but it wouldn't activate until I walked off and on again). I could live with having the party walk to it in this case, but there might be a point later on in the scenario when I really need the special to be triggered just by entering the town.

Now, here's the thing - I looked to see how it's done in VoDT and ASR (it's probably done in ZKR too, but I don't remember), and it seems to be this: using VoDT as an example, when the party enters Sweetgrove, the game checks to see whether the party has activated the quickfire machine yet, in which case they'll have been sent to Sweetgrove via a forced stairway. If they have, they get a few dialogue boxes, then a reward, and then the scenario ends. If they haven't activated the quickfire, the game checks to see whether the party has visited Sweetgrove before. If they have, nothing happens, if they haven't, a dialogue box comes up. All this happens just by the special nodes existing in Sweetgrove's list. Zaskiva has much the same thing, only it checks to see if you've inadvertently killed Lord Volpe, and if you have, you die.

I made a tiny scenario containing three towns, representing Fort Talrus, Sweetgrove and wherever it is in the school that the quickfire machine is located (Major Waste Repository?) I copied the above as simply as I could, putting a special in the third town which changed flag 0,0 and then sent the party to the second town via a forced stairway. The second town was supposed to check the value of 0,0 and display a dialogue box accordingly. Did it happen? Nope. I like to think I understand specials fairly well and I can't see anything vital I'm not doing, so unless someone can enlighten me I'm guessing it's a bug. Why it only affects my scenario and not the official BoE ones though (I've played through the beginning of VoDT and the Sweetgrove message comes up), I have no idea.

Edited by Azalea
Link to comment
Share on other sites

1 hour ago, Azalea said:

All this happens just by the special nodes existing in Sweetgrove's list.

This is certainly not true. One of those special nodes is the start of the chain, and it must be referenced from somewhere, most likely in the Town Details or Advanced Town Details screen. Nodes don't run just because they exist. Something has to call them intentionally.

Link to comment
Share on other sites

Well, you have just answered my prayers! There is indeed a section for this in Advanced Town Details. I don't recall ever using that before, yet I'm sure I got this to work in the umpteen scenarios I never finished as a child. Oh well, I remember that menu having seen it just now. Honestly, it would be really handy if specials had a 'Called By' section so you don't have to trawl through all your specials, or even towns, looking for the number, like I was doing with VoDT.

This has made my day, especially as I didn't think I'd get a reply, certainly not so soon.

 

Edit: I tell a lie, it's coming back to me. I think I did used to know that existed, probably because at some point I read the entire scenario editor instructions from start to finish before I even let myself begin a scenario. However, it's been years since then. Years of thinking my BoE days were over.

Edited by Azalea
Link to comment
Share on other sites

  • Azalea changed the title to Dialogue boxes on entering town not showing up? [SOLVED]
On 9/2/2022 at 8:31 PM, Azalea said:

Honestly, it would be really handy if specials had a 'Called By' section so you don't have to trawl through all your specials, or even towns, looking for the number, like I was doing with VoDT.

That's a good idea. I've opened an enhancement request for it on the GitHub.

Link to comment
Share on other sites

Hi, just for information,
I have a special branch of cboe : https://github.com/fosnola/cboe/tree/special_code ° where I replaced the old methods to define specials by scripts¹. It allows to load an old scenario, then you can save it in "my" new format, unzip the scenario and look for the "sdf(...)" strings. I often use this method when I test an unknown scenario and I'm stuck ( even if there are some sdfs that are stored elsewhere : sdf to set to 1 when a creature dies, ... )  

 

Note:

° I work on Mac, so it must be easily compilable on OsX ; for other platforms, it will be necessary to rework the platform projects :-~
¹ You should not use it to create new scenarios.

 

For instance, a few lines taken from grep -r "sdf(" valleydy

./out/out0~2.code:if (!once_set_sdf(206,4)) return();
./out/out0~2.code:if(i0==0) sdf(206,4)=0;
./out/out0~2.code:if (!once_set_sdf(206,5)) return();
./out/out0~2.code:if (!once_set_sdf(206,6)) return();
./out/out0~2.code:      sdf(206,6)=0;
./out/out0~2.code:if (!once_set_sdf(206,7)) return();
./out/out0~2.code:      sdf(206,7)=0;
./scenario.code:if(sdf(2,5)==1) jump(1);
./scenario.code:if (!once_set_sdf(100,6)) return();
./personalities/talk4.xml:                <![CDATA[int res=buy_sdf(500,4,2,1);
./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
./towns/town8.code:if (!once_set_sdf(8,0)) return();
./towns/town8.code:if (!once_set_sdf(8,1)) return();
./towns/town8.code:if (!once_set_sdf(8,2)) return();
./towns/town8.code:if (!once_set_sdf(8,3)) return();
./towns/town8.code:if (!once_set_sdf(8,4)) return();
./towns/town8.code:if(i0==0) sdf(8,4)=0;

 

Edited by osnola
Link to comment
Share on other sites

15 hours ago, osnola said:

where I replaced the old methods to define specials by scripts

Doesn't this kinda defeat the point of the special node system…?

 

I gather that you consider it useful for determining where SDFs are used, which is actually another good enhancement to add, but we were talking about where special nodes are called.

Link to comment
Share on other sites

10 hours ago, Celtic Minstrel said:

Doesn't this kinda defeat the point of the special node system…?

This replaces it with something more powerful, that is, 

 

  • if I'm not mistaken, you can do at least the same things as with the old and new special node system,
  • you can code complex things in one block (instead of having to write k small specials)
  • I try to add some new functions° and it is relatively easier to add a new one,

a similar change that appears in Blades of Avernum except that Jeff does this for all specials while in my code there are still a few integers for terrain/objects/monsters that remain and mean calling a local/global special.

 

Quote

I gather that you consider it useful for determining where SDFs are used, which is actually another good enhancement to add, but we were talking about where special nodes are called.

Oops, using scripts helps a bit, i.e. I usually open in an editor the town/outdoor .code file, then look for "jump(8)" if I want to know where the special 8 is called. I also use the "<special ..." command in the town/outdoor xml files. But of course, that doesn't solve all cases. 
To summarize, adding a function to do this, is indeed a good idea.

 

° I try to maintain in bad english (ie. frenglish) a small doc https://github.com/fosnola/cboe/blob/special_code/doc/HowToWriteSpecial.md  .

Edited by osnola
Link to comment
Share on other sites

But in my mind, the point of the existing node system is the ease of use for people who aren't used to coding. A written scripting language presents a higher barrier to entry. The node system could certainly be improved, but I don't think replacing it with scripting is desirable for the most part.

 

(Scripting also makes it more difficult to create a tool that will list references to an SDF or special node.)

 

That said, I don't think it's bad to have scripting as an option; in particular, if you actually compile the scripts down to my existing special node syntax, then scripting could exist as a design-time auxiliary tool.

Link to comment
Share on other sites

Quote

But in my mind, the point of the existing node system is the ease of use for people who aren't used to coding. A written scripting language presents a higher barrier to entry. The node system could certainly be improved, but I don't think replacing it with scripting is desirable for the most part.

As for the complexity between the two methods, it's true that it's different; at the beginning, the special nodes mechanism is surely the easiest, but as soon as you want to do non-basic things, I'm not so sure (you have to create 5 or 6 specials to do this, ...). 

 

The only thing I can really talk about is the readability of the result: when I search for something, and I find° :

if (sdf(2,3)==3)
   jump(9);
display_message([mess(3),mess(4)]);
...

I quickly understand what it is about, I make a shift click on the mess(3) to see the message 3, then on 'jump(9)' to see the special with number 9.
On the other hand, when I was doing the same thing with the old version of the editor, I was always a bit lost, I had to look at the type of the special, search in the list of parameters, those that are potentially important, ...

 

° in the mini editor of Scenario Editor that I added and that needs to be improved. For those who have a Mac and want to test, there is a compiled version of the special_code branch in https://github.com/fosnola/cboe-distrib/tree/main/MacOsXExperimental

 

Notes:

- I add some mechanisms to make the writing of code easier in the mini-editor : a button to check that the syntax of a code is ok, you can choose the enum, picture, sound as before or using a enum name button:no, pict:terrain, ... The functions can have default parameters. You can also click on the name of a function and see what it does (in broken English :-~ ).

- The main remaining problem is that will have to work on the list of functions we want, their names, their arguments. I tried to do my best, but ...

 

Quote

That said, I don't think it's bad to have scripting as an option; in particular, if you actually compile the scripts down to my existing special node syntax, then scripting could exist as a design-time auxiliary tool.

 

Even ignoring the fact that I added a lot of functions, converting a script to special nodes doesn't make much sense in my opinion, scripts allow to write code in a too flexible way.

 

What may be feasible, is to propose to users to automatically write code snippets by calling the old interface, i.e. clicking on a "Generic Starway" button, ... which displays the old dialog, ..., and ends up inserting the corresponding code at the current location .

 

Quote

(Scripting also makes it more difficult to create a tool that will list references to an SDF or special node.)

 To find the sdf, the calls to the special, yes it's true that it's more complicated to write ( even if I've already created a function that checks the existence of the calls of specials that are in the scripts : check_unavailable_codes ).

Edited by osnola
Link to comment
Share on other sites

1 hour ago, osnola said:

Even ignoring the fact that I added a lot of functions, converting a script to special nodes doesn't make much sense in my opinion, scripts allow to write code in a too flexible way.

?

 

The special node syntax I designed was intended to evoke assembly languages. Compiling complex code down to an assembly language (technically, machine language) is a fairly normal thing to do. I think in theory, anything you write in your scripting language should be able to be reduced to a series of nodes (unless of course you've added new features that don't have corresponding node types). There are certainly some complications, such as variables, that might make that trickier, but I believe it should be doable, and it means both systems can sit side-by-side without needing two separate interpretation engines in the actual game.

 

By the way, does your scripting include the concept of "pointers" that I introduced in the node engine, or is that removed in favour of variables or something?

Link to comment
Share on other sites

Quote

?

 

The special node syntax I designed was intended to evoke assembly languages. Compiling complex code down to an assembly language (technically, machine language) is a fairly normal thing to do. I think in theory, anything you write in your scripting language should be able to be reduced to a series of nodes (unless of course you've added new features that don't have corresponding node types). There are certainly some complications, such as variables, that might make that trickier, but I believe it should be doable, and it means both systems can sit side-by-side without needing two separate interpretation engines in the actual game.

Yes, this is probably possible, but I'm afraid that without complex mechanisms to simplify the result, it will generate a lot of special nodes and the result will become totally unreadable.

 

Quote

By the way, does your scripting include the concept of "pointers" that I introduced in the node engine, or is that removed in favour of variables or something?

I remove it in favour of variables because it is possible to write directly "jump(sdf(2,3)+4);", ... and define static variables of type int (or string, list of int, list of string) that are persistent. Ie. if necessary, it can be simulated with static scenario variables: s_int0, s_int1, ... that can be accessed anywhere (using scenario.s_int0 if you are not in the scenario context).

 

I also did not implement the part about global strings as it is now possible to write:

print_string(["The terrain name is "+get_terrain_name(get_special_terrain()),"The ..."]);

and/or use string's variables to store/modify string.

 

Notes:
- if necessary, I can reimplement these mechanisms, but I'm not sure how often they are used but I fear that when they are, the code quickly becomes unreadable (ie. using static variables probably makes the code longer, but it can remain readable).

- using a static list of int is probably better [int] s_params; then the code can be s_params=[2,4,5]; jump(8);  and in label8: if (s_params.empty()) do_A(); elif (s_params.size()==1) do_B(s_params[0]); ...

- the right solution is probably to allow to define in the code new functions, it's possible but I didn't have the courage to implement it.

Edited by osnola
Link to comment
Share on other sites

49 minutes ago, osnola said:

Yes, this is probably possible, but I'm afraid that without complex mechanisms to simplify the result, it will generate a lot of special nodes and the result will become totally unreadable.

It's not meant to be readable. It's meant to be interpreted by the game engine.

 

50 minutes ago, osnola said:

if necessary, I can reimplement these mechanisms, but I'm not sure how often they are used but I fear that when they are, the code quickly becomes unreadable (ie. using static variables probably makes the code longer, but it can remain readable).

It may be better to keep them around for compatibility reasons, if nothing else. Although, admittedly, pointers are not used in any extant scenario… but global text certainly is.

Link to comment
Share on other sites

Quote

It's not meant to be readable. It's meant to be interpreted by the game engine.

It remains that even incredibly difficult to do. For example, if someone writes:

[int] hidden_towns=get_list_towns(town:hidden);
if (hidden_towns.empty())
    return();
if (hidden_towns[0]<3) {
    [string] hints=["Hint1","Hint2","Hint3"];
    dialog_message(["You receive an hint about town "+to_string(hidden_towns[0]),hints[hidden_towns[0]]]);
    set_town_visibility(hidden_towns[0],true);
}
...

I'm not sure if it's worth the hassle to translate it and/or how to do it.

 

Quote

It may be better to keep them around for compatibility reasons, if nothing else. Although, admittedly, pointers are not used in any extant scenario… but global text certainly is.

I will try to find the time to do that...

Edited by osnola
Link to comment
Share on other sites

15 hours ago, Celtic Minstrel said:

But in my mind, the point of the existing node system is the ease of use for people who aren't used to coding. A written scripting language presents a higher barrier to entry. The node system could certainly be improved, but I don't think replacing it with scripting is desirable for the most part.

This. I've dabbled in coding enough to have a fair idea what's going on in that snippet of code from VoDT, but I haven't done enough of it to be able to read it without a great deal of effort. Interpreting the language is much harder work than just learning which information I need to put where in an interface that does that for me.

Link to comment
Share on other sites

3 hours ago, osnola said:

It remains that even incredibly difficult to do.

Yeah, sure, it's difficult. It's basically "writing a compiler". It can certainly be done, but would not be easy.

 

I don't know how your snippet would be compiled down to nodes. Perhaps some new node types are needed to support what you're doing there. But it's certainly possible to do.

Link to comment
Share on other sites

Just for note, if we choose to have scripts and also add basic templates to help build pieces of code, for example, a template for "Stuff Done Flag", we can generate the script:

//----start_template("Stuff Done Flag",7,5,1,4,-1,-1,6)----
if (sdf(7,5)>=1)
    jump(4);
jump(6);
//----end_template("Stuff Done Flag",7,5,1,4,-1,-1,6)----

then it will be enough to look if the player clicks in a template zone; in this case, we reopen the dialog which corresponds to "Stuff Done Flag" (verifying first if the intermediate code was modified or not).

Edited by osnola
Link to comment
Share on other sites

On 9/8/2022 at 4:37 PM, osnola said:
Quote

It may be better to keep them around for compatibility reasons, if nothing else. Although, admittedly, pointers are not used in any extant scenario… but global text certainly is.

I will try to find the time to do that...

I just added some functions : see the end of  https://github.com/fosnola/cboe/blob/monsterCode/doc/HowToWriteSpecial.md .

 

Note:

- monsterCode is a temporary branch, I usually create such branch to test something before deciding to keep them or not; here as I play a singleton, at the same time in Queen's Wish 2, the only thing I test is if this branch compiles, ...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...