1.16 Campaign: A Rough Life - version 1.2.9

Discussion and development of scenarios and campaigns for the game.

Moderator: Forum Moderators

Post Reply
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

I discovered the file I uploaded the other day has incorrect image pointers for skellies and Jacques's portraits. Sorry! Here's a corrected version with some other slight code changes as well. I have been playing this one all day, so I know it's OK (though not sure what effect some of my commented bits may have in the long run).
Attachments
01_Led_Astray.cfg.zip
(9.96 KiB) Downloaded 418 times
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Wow. Just wow. Thank you Jamie, you definitely earned a place in the campaign's credits. 8)
Jamie wrote:Where is Mosh? When does this story take place? What is the name of Bombasan's kingdom? Where is Bombasan's kingdom?
This campaign, from the very start, never had many bindings to mainline. So we can listen to the other users' opinions, and use the options that they like more.
Jamie wrote:"#result=continue" appears in 01_, 02_, 06_, 10_, 12_, 13_, 14_, 15_, 15a, 15b and 16 (with "_no_save" appended); is this a custom "result" value that's not being used or an obsolete value the game used to recognize but no longer does?
Until 1.6, the result=key supported four values: victory, defeat, continue and continue_no_save. When I lifted the campaign for 1.8, continue and continue_no_save needed to be replaced with victory, plus some other keys to control the behaviour. So yes, they can be removed.
Jamie wrote:{ai/aliases/stable_singleplayer.cfg} exists in 01_-05_; 07_-09_; 11_ and 13_-15_, but not the other files.
In scenario 1, it is necessary due to the Lua AI code, otherwise it crashes. In the other scenarios, it shouldn't be necessary (they don't use Lua stuff), so I'll remove it.
Jamie wrote:"income=0" —income defaults to zero so I think this attribute is redundant. It's not hurting anything, but could be removed. All the scenarios where J might actually have a non-zero income use {INCOME x y z} instead. (applies to 01_-04_, 06_, 07_ and 10_)
Yes - that line causes no noticeable effects, so I always missed it. About the INCOME macro: it is needed only if the scenario has differentiated income between the difficult levels. If the income stays the same on all three diffilcult levels, the gold= key works fine.
Jamie wrote:Var "Jacques_store" {VARIABLE Jacques_store 0} is defined in scenario 01_ and then does not appear again until scenario 05_ where it is cleared {CLEAR_VARIABLE Jacques_store}, but not apparently used for anything else.
Once again, it may be a place of orphan code without any noticeable effect, so I missed it. Thank you for pointing it, in case that it has no effect it'll be gone for good.
Jamie wrote:Lt. Popper is currently modified to loyal with no random traits but could be assigned "no upkeep" with "canrecruit=yes" and allowed random traits making five lines of code into one. Is there some reason to prefer the current more verbose code given that the player never controls Popper? (applies to 02_ and 07_)
Yes: if we give him canrecruit=yes, he will gain the golden crown, giving the player the false impression that he may recruit. It's possible to mask it by assigning the bronze ring as well, but some parts of the crown overlay will stick out.
Jamie wrote:There is a message displayed that encourages the player to kill Jabb for a bonus. If I wait for that message to display I find it very difficult to kill Jabb for the bonus.
Of course, Jacques isn't supposed to know that the Goblin will do the same path in a loop. The message appears when Jacques actually realizes that there is an anomaly.
Jamie wrote:Two "attack" events and a "last breath" event have nested "if" statements that check two conditions, one condition per if statement.
I agree that it could be simplified - even with [filter_condition]. I just didn't notice them - it could happen when updating an old campaign.
Jamie wrote:Why is Gronar given "random_traits=no"? He just dies right away so it makes no difference so why waste a line of code on him?
Because he's the leader of a side in scenario 3. It will be at least peculiar if he gains traits out of this air in the next scenario - even if it is only for a moment.
Jamie wrote:Why do we give J new loyal units instead of recalling existing loyal units? does player need this many loyal units to run the campaign? (It's not a big deal, I'm just asking if this is a game balance issue that has been thought about, or is it accidental.)
Honestly, I have no idea. These units were already loyal when I first started updating it, so I always assumed that the original author wanted them to be loyal as well. For what reason, I don't know.
Jamie wrote:#profile="portraits/Arbor.png" -what happened to the arbor pic? Is there a reason to leave this comment in?
In 1.6, the current Wose portrait was not in mainline. So Jacques_Fol backported it inside the campaign. Now that said portrait is mainlined, the line can be removed.
Jamie wrote:Why is the S. Queen placed hidden at 1,1 then unhidden and teleported to 19,18 ? Why not place her directly at 19,18 in her side tag and hide her there? Is there a problem revealing her later if a unit occupies her hex that is solved by teleporting her in?
When you use [hide_unit], the unit is still here and can still be attacked. It just cannot be seen. The other option (creating her in the moveto event) will require to get rid of her [have_unit] checks and replace them with some variable checks.
Jamie wrote:Kyoko is defined to be an Elvish Princess (level 2). I think that means the Elvish Maiden unit is not used anywhere in the campaign. I think it would be better to start her as a Maiden and let her advance in this scenario as she did in a previous campaign version. Why was it changed?
Hint: Kyoko is ill only for this scenario. In the next scenarios she will fight normally, and I changed her so I was able to use a custom sprite and an AMLA system, instead of using a reskinned Shaman line.
Jamie wrote:In "prestart", after objectives are defined, loyal units are recalled individually and placed on specific map locations;
I think that I'll implement your code; again, this was a leftover from 1.6, where search_recall_list didn't exists.
Jamie wrote:but if Carl has advanced, this won't trigger and the line is missed. That could be deliberate, but I like the line and would like advanced Carl to say it if he exists, so I suggest:
Of course I'll correct it, but I won't wrap the [message] inside the [if] check: in case that Carl isn't alive, the message will be just skipped anyway.
Jamie wrote:Is this yours, Elvish_Hunter or is it Jacques_Fol's?
That compatibility.cfg file is mine, and I need it because I still have some savegames that need it. When I'll update the campaign to 1.11, it will disappear.
Jamie wrote:The level ends when Jacques is captured (killed), or when J kills the Goblin trader or when turns run out.
Problem: on turn 20, the Peasants will flee. In the unlikely case that the Trader and the slimes are dead, what should happen on turn 20?

I hope that I answered to all your questions. :)
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

Hey, thanks for all your great answers!
{ai/aliases/stable_singleplayer.cfg} exists in 01_-05_; 07_-09_; 11_ and 13_-15_, but not the other files.
In scenario 1, it is necessary due to the Lua AI code, otherwise it crashes. In the other scenarios, it shouldn't be necessary (they don't use Lua stuff), so I'll remove it.
I have been reading more about the RCA AI and I have seen in the documentation that {ai/aliases/stable_singleplayer.cfg} is supposed to be in each [side] tag that contains an [ai] tag, but since there is no longer any fallback AI and RCA AI is the default, I don't know if it makes any difference. I posted a query on the wml workshop forum about stable_singleplayer.cfg. A respondent pointed out the [stage] tags in the lua code make it necessary and require it to come after the ai tag (when the convention is to place it immediately before ai tags). I have added playing the scenario and doing an "inspect" to verify aspect settings to my list of things to do.
Lt. Popper is currently modified to loyal with no random traits but could be assigned "no upkeep" with "canrecruit=yes" and allowed random traits making five lines of code into one. Is there some reason to prefer the current more verbose code given that the player never controls Popper? (applies to 02_ and 07_)
Yes: if we give him canrecruit=yes, he will gain the golden crown, giving the player the false impression that he may recruit. It's possible to mask it by assigning the bronze ring as well, but some parts of the crown overlay will stick out.
There's nothing wrong with the code as it is, I just thought it could be simplified. I thought perhaps he was made loyal just to make him not cost any upkeep. But since none of the allies do any recruiting at all, it doesn't really matter what their units cost (I now realize). I have since played the scenario over several times and P looks much better with the brass ring than either with the crown or without it. So I agree—I have discarded my original thought—no change is needed here. On the other hand P also appears in 04_ to break up the fight and there he is not loyal and does have random traits. But there he is on side 1, so making him loyal would put him on J's recall list and he'd have to be scrubbed. Is he being created from scratch each time?

The same question for Gronar:
Why is Gronar given "random_traits=no"? He just dies right away so it makes no difference so why waste a line of code on him?
Because he's the leader of a side in scenario 3
It's a good answer except in 03_ Gronar is not set "random_traits=no". So leaders automatically don't get random traits? And is he created from scratch each time?
There is a message displayed that encourages the player to kill Jabb for a bonus. If I wait for that message to display I find it very difficult to kill Jabb for the bonus.
Of course, Jacques isn't supposed to know that the Goblin will do the same path in a loop. The message appears when Jacques actually realizes that there is an anomaly.
Yes, the message makes sense. And the alert player will note the bonus for killing Jabb is added to the objectives at turn 3. The message is just more encouragement to go after him that pops up around turn 8 or so. I don't really want to change any of that. I just think killing Jabb can be very difficult. I guess it's a fine line between offering a challenge and causing frustration. As it is, only the best players will ever get the reward and it feels more frustrating than challenging to me. But I can live with it. On the bright side, it gives the scenario replay value :)
Why do we give J new loyal units instead of recalling existing loyal units? does player need this many loyal units to run the campaign? (It's not a big deal, I'm just asking if this is a game balance issue that has been thought about, or is it accidental.)
Honestly, I have no idea. These units were already loyal when I first started updating it, so I always assumed that the original author wanted them to be loyal as well. For what reason, I don't know.
Well, after playing through on Hard difficulty, I think I understand the need for more loyal troops! I withdraw the question.
When you use [hide_unit], the unit is still here and can still be attacked.
Hmmm.. I tried putting her on hex 19,18 hidden and then just unhiding her and it didn't work. Her escorts all showed up, but she didn't. Adding a "redraw" tag didn't make any difference. I tried once with a friendly unit standing on 19,18 and once with it clear–it didn't make any difference. She doesn't seem to be there at all. I cannot attack that hex. Anyway, teleport works fine. I'm just trying to understand the way the hide/unhide tags work.
Kyoko is defined to be an Elvish Princess (level 2). I think that means the Elvish Maiden unit is not used anywhere in the campaign. I think it would be better to start her as a Maiden and let her advance in this scenario as she did in a previous campaign version. Why was it changed?
Hint: Kyoko is ill only for this scenario. In the next scenarios she will fight normally, and I changed her so I was able to use a custom sprite and an AMLA system, instead of using a reskinned Shaman line.
OK. Then do we need the custom unit definition in "units/Elven_Maiden.cfg". Is that file used to profile Elvish Maiden units in the help system? Or is it necessary for the second level unit to exist to have the first level also defined?
but if Carl has advanced, this won't trigger and the line is missed. That could be deliberate, but I like the line and would like advanced Carl to say it if he exists, so I suggest:
Of course I'll correct it, but I won't wrap the [message] inside the [if] check: in case that Carl isn't alive, the message will be just skipped anyway.
If Carl dies in this scenario the line will be skipped, but if Carl died in a previous scenario he will be replaced by a generic Orcish Grunt who may still be alive to speak the line.
The level ends when Jacques is captured (killed), or when J kills the Goblin trader or when turns run out.
Problem: on turn 20, the Peasants will flee. In the unlikely case that the Trader and the slimes are dead, what should happen on turn 20?
Ouch! OK, I'll think about this some more.

One more thing in 05_More_Hard_Labor: There is a set of "set recruit" tags at the end of the "start" event that seem to be redundant. I thought maybe they were needed because J is changed to Sand Trapper at start or on level advance (if he's still a thief when starting the scenario), but I tested this and J is still able to recruit after the change without this extra set of tags.
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Jamie wrote:Is he being created from scratch each time?
Yes, he is.
Jamie wrote:So leaders automatically don't get random traits? And is he created from scratch each time?
Yes, leaders don't get trait, unless you assign them some or you use random_traits=yes. Another possible solution is to store both Popper and Gronar, and unstore them when needed.
Jamie wrote:Hmmm.. I tried putting her on hex 19,18 hidden and then just unhiding her and it didn't work. Her escorts all showed up, but she didn't. Adding a "redraw" tag didn't make any difference. I tried once with a friendly unit standing on 19,18 and once with it clear–it didn't make any difference. She doesn't seem to be there at all. I cannot attack that hex. Anyway, teleport works fine. I'm just trying to understand the way the hide/unhide tags work.
Can I see your code? Personally, I remember very well the problem, because once, when playing Fate of a Princess, I was attacked by... an invisible Fog Clearer! Now the bug is solved, but at the time was quite funny. Except that, in the case of ARL, such behaviour will cause a bug.
Jamie wrote:OK. Then do we need the custom unit definition in "units/Elven_Maiden.cfg". Is that file used to profile Elvish Maiden units in the help system? Or is it necessary for the second level unit to exist to have the first level also defined?
They're needed just for compatibility with former versions. When porting to 1.11, this necessity will no longer exist, and they'll be removed.
Jamie wrote:If Carl dies in this scenario the line will be skipped, but if Carl died in a previous scenario he will be replaced by a generic Orcish Grunt who may still be alive to speak the line.
Good point. So, the message will be said by Carl, if available; else, it'll be said by any Orcish unit; in case that there are no Orcs on the map for side 1, the message will be skipped.
Jamie wrote:One more thing in 05_More_Hard_Labor: There is a set of "set recruit" tags at the end of the "start" event that seem to be redundant. I thought maybe they were needed because J is changed to Sand Trapper at start or on level advance (if he's still a thief when starting the scenario), but I tested this and J is still able to recruit after the change without this extra set of tags.
Good catching! I'll delete it. :)
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

Once again, thanks for the great answers! I am uploading the first 7 files below. I have picked them over pretty well and am mostly satisfied that I can't make them any better, though there are still bits I don't quite understand and a few outstanding problems I mention below. I am very gratified to be able to work on this and I hope you like the story changes, but take what you want and leave anything you don't like. I won't be offended. I will continue with the second half of the files and should have them done in a week or two.
Elvish_Hunter wrote:
Can I see your code?
There's not much to it. In the side tag I changed:

Code: Select all

        [hide_unit]
            x,y=1,1
        [/hide_unit]
to

Code: Select all

        [hide_unit]
            x,y=19,18
        [/hide_unit]
and then in the "moveto" event I changed:

Code: Select all

        [unhide_unit]
            x,y=1,1
        [/unhide_unit]
to

Code: Select all

        [unhide_unit]
            x,y=19,18
        [/unhide_unit]
and removed the teleport macro. Don't know why that didn't work. Then I tried:

Code: Select all

        [unhide_unit]
            x,y=1,1
        [/unhide_unit]
	     [redraw]
	     [/redraw]
but that didn't help it any, so I just put it all back the way it was.

In both 02_Captivity and 07_Confronting_the_Traitor there are some filters in the minion "die" events that look like this:

Code: Select all

            [filter]
                type=Wolf
                [or]
                    type=Giant Scorpion
                [/or]
                [or]
                    type=Troll Whelp
                [/or]
                [or]
                    type=Giant Spider
                [/or]
            [/filter]
The first filter in 07_ looks much better:

Code: Select all

        [filter]
            type=Wolf,Giant Scorpion,Troll Whelp,Giant Spider
        [/filter]
so I changed them all to this simpler form.

Throughout the files I commented out some of the ai aspect tweaks, mostly ones concerning "village_value" where there are no villages and "leader_value" where there is no fighting. These shouldn't affect the gameplay at all if I understand them correctly.

I noticed that multiple filter conditions default to AND logic so I took out the redundant [and][/and] tags I had put in previously. No biggie, but it saves a couple lines.

Oh, and I changed my mind about the little tree in 05_. I thought it was superfluous and wanted to remove it, but now I think it represents Arbor and I want to keep it.

A more substantial change in files 05_ and 07_… each has a "post_advance" event that is triggered only if J entered the scenario as a thief. For some reason there are two separate variables that track this. Here's what 05_ looks like: in "start"

Code: Select all

        {CLEAR_VARIABLE Jacques_store}
        {CLEAR_VARIABLE transition}
    ...
        {STORE_UNIT_VAR id=Jacques type Jacques_type}
        [switch]
            variable=Jacques_type
            [case]
                value=Thief
                [set_variable]
                    name=transition
                    value=1
                [/set_variable]
                [message]
    ...
        [/switch]
        {CLEAR_VARIABLE Jacques_type}
and then later:

Code: Select all

    [event]
        name=post_advance
        [filter]
            id=Jacques
        [/filter]
        [switch]
            variable=transition
            [case]
                value=1
                [message]
    ...
                [set_variable]
                    name=transition
                    add=1
                [/set_variable]
            [/case]
            {CLEAR_VARIABLE transition}
            {VARIABLE transition 0}
        [/switch]
    [/event]
I can't see that "transition" is doing anything more than "Jacques_type" is doing here. This is what I recommend and have been play-testing:

Code: Select all

    [event]
        name="prestart"
    ...
        {STORE_UNIT_VAR id=Jacques type Jacques_type}
    ...
    [event]
        name="start"
        [switch]
            variable="Jacques_type"
            [case]
                value="Thief"
                [message]
    ...
        [/switch]
and later

Code: Select all

    [event]
        name="post_advance"
        [filter]
            id="Jacques"
        [/filter]
        [filter_condition]
            variable="Jacques_type"
            value="Thief"
        [/filter_condition]
        [message]
    ...
I then make sure to clear the var before exiting the victory condition end level tags. I am assuming that a defeat that sends the player back to the main menu will dispose of all campaign vars automatically. If that's not true then we should clear the var more conscientiously. I think this is much simpler code and as far as I can tell it does everything we want. I made a similar change in 07_ though 07_ doesn't have the same stuff going on in the "start" event. Perhaps this could be even simpler. I don't fully understand the filter tags (I am coding from example here). Do we need both a "filter" and a "filter_condition" to accomplish this?

Now, a couple of things I can't figure out:

My "while" loop suggestion for the war drums in the 07_ "victory" event doesn't work at all. Depending on what I put into the loop: 1) I get it to play endlessly. It doesn't stop, even when loading the next scenario or exiting to the main menu—until all repetitions have played out. I don't know how to turn it off. I first tried

Code: Select all

        [while]
        [have_unit]
        id="Jacques"
        [/have_unit]
        [do]
        [sound]
            name="ambient/wardrums.ogg"
            repeat=5
        [/sound]
        [/do]
        [/while]
as my condition, assuming that when the scenario ended the while loop would terminate; but it doesn't. Then I tried "id=King Bombasan" as my condition and killed him off before the scenario ends, but that didn't stop the loop either, which really surprised me. The "while" seems to act just as an "if". 2) the war drums play but no further messages are shown and the scenario never goes to conclusion. (I don't remember what code caused his, but it happened with one variation I tried.) I have posted a query on the wml workshop forum about this whole problem. Part of the problem is that if one zips through the dialog (without reading perhaps), the drum sound will continue into the next scenario or even play in the main menu if you quite the campaign. It does this with the current code as well as in the "while" loop, so just not using the loop doesn't really fix things.
My current compromise is to shorten the repeat to 3 so that the drum sound is likely to quit before the end even for very fast readers (it probably won't quite for people just spacing through without reading), and then putting a very short second drum in at the end that will not play long into the next scenario, but will highlight the dramatic last message. My only other thought is to make the .ogg file longer and play it in a "music" tag instead of a "sound" tag, but I'm not set up to manipulate sound files on my Mac. Any thoughts?

Another issue I want to explore is making Bombasan move when the narrator says he, "runs to embrace Kyoko…" I have added small movements to J and K in 12_Flip_of_Destiny as they talk, but that is easy because you always know exactly where they are. Here, the player could have put K virtually anywhere on the map by the time B utters his line. I don't know how to move him adjacent to K since I don't know where she is going to be, but I think there must be a way to get her location information and pass it to B. I don't want to stop to work on this right now though. I want to finish the second half of the files first.

Finally, I wanted to run these files through wmllint before handing them off, but I am having a great deal of difficulty getting "enchant" installed (I have read what help is available on the internet to no avail). I have renewed respect for anyone who puts together a campaign from scratch.

Well, that's all for now.
Attachments
A_Rough_Life.zip
First seven scenarios only, with comments
and three slightly modified unit files
(58.91 KiB) Downloaded 372 times
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

I was hoping to move on to 08_ today, but I got caught up in some housekeeping in 07_Confronting_the_Traitor. I took a peak in a save file to see what was going on with the "Kyoko_safe" variable (more about that below) and I discovered a raft of variables that had not been cleared from previous scenarios:

Code: Select all

	[variables]
		Kyoko_safe=1
#		arbor_met=yes
#		count=10
		damage_inflicted=9
		enemies=1
#		escape=0
		goblin_attack=3
		heal_amount=32
#		peaks_clear=yes
		side_number=1
#		triggered_scorpion=yes
		turn_number=3
...
	[/variables]
The commented ones are the ones that should have been cleared, so I added "clear variable" macro tags in 02_ and 05_ the two files where these are defined and used.
05_ "victory" event:

Code: Select all

                [/endlevel]
		          {CLEAR_VARIABLE Jacques_type}
		          {CLEAR_VARIABLE arbor_met}
		          {CLEAR_VARIABLE peaks_clear}
		          {CLEAR_VARIABLE triggered_scorpion}
            [/then]
02_ "victory" event:

Code: Select all

                [/endlevel]
				    {CLEAR_VARIABLE count}
				    {CLEAR_VARIABLE escape}
            [/then]
And I added to 07_:

Code: Select all

    [event]
        name="victory"
        {CLEAR_VARIABLE Jacques_type}
        {CLEAR_VARIABLE enemies}
        {CLEAR_VARIABLE Kyoko_safe}
The reason I was looking at "Kyoko_safe" is:
Spoiler:
When I stepped through the variable's usage I couldn't see any problem. I finally tracked down a couple of small things. To make a long story short, I made these changes:

Code: Select all

    [event]
        name="attack"
        first_time_only="no"
        [filter]
        ...
        [/object]
        [if]
            [variable]
                name="Kyoko_safe"
                equals=0
            [/variable]
        	[then]
            	[message]
            	...
	        [/then]
	    [/if]
	    [if]
            [variable]
                name="Kyoko_safe"
                equals=1
            [/variable]
	    	[then]
            	[message]
            	...
            [/then]
        [/if]
This is not as elegant as what was there, but it works:
Spoiler:
Also, I got an answer to my query on wml workshop about playing wardrum.ogg. It was suggested we use [sound_source]. I played around with it a little. It would do exactly what we want, except I can't get it to start playing inside the event. Apart from that, it solves all the problems with the sound tag timing and running over etc. Oh, well...
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

oops! I said the variables were in 02_ but they are in 03_Hard_Labor.
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Once again, thanks for your feedback!
Jamie wrote:Finally, I wanted to run these files through wmllint before handing them off, but I am having a great deal of difficulty getting "enchant" installed (I have read what help is available on the internet to no avail). I have renewed respect for anyone who puts together a campaign from scratch.
I'll assume that you already installed Python 2.7.3 and that you are on Windows. To solve the problem, you need to install the Enchant library, also known as PyEnchant.
Go here: http://pythonhosted.org/pyenchant/download.html , download the file pyenchant-1.6.5.win32.exe and run it. That should be enough.

EDIT: I just noticed that you're on MacOS. In that case, the files to download are the following: pyenchant-1.6.5-py2.5-macosx-10.4-universal.dmg
or pyenchant-1.6.5-py2.6-macosx-10.4-universal.dmg, depending on your Python version. I can't help you much more, because I don't have a Mac, sorry.
Anyway, don't worry about that: once that you finished revising all the scenarios, I'll do a final run through the maintenance tools (wmllint/scope/indent) before uploading the campaign on the server :) .
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

Elvish_Hunter wrote:
files to download are the following: pyenchant-1.6.5-py2.5-macosx-10.4-universal.dmg
Thanks, but that is the package I have. Apparently it's only something called "the bindings" and requires another component (the actual list of words that comprise the dictionary) to work. My understanding of Enchant is that one of it's advantages is that it can use many different dictionaries, including the system dictionary already available to my Mac applications generally, but I can't seem to get it to use any. I downloaded something purporting to be the main English language dictionary, and I was careful to make sure I have the correct versions for wmllint (it only runs on older versions of python) and added the correct path for the shell routine, but it still quits with an error message that no dictionary is available. Oh well. I'm glad you are willing to clean up the files, but I'll still try to have them as clean as possible when I hand them off.

I want to bring up a complicated matter to explain. Please bear with me. There are three pieces of code that work together to control what message is displayed when J transforms from the Thief/Rogue/Assassin (T/R/A) leveling path to the Sand Trapper/Sand Ranger (ST/SR) path and finally to Battle Commander (BC). This code also tells the game to make these switches. This code starts with a variable named "transition" which is used in a [switch] tag in the "start" event and again in a "post_advance" event. I already deleted this variable from files 05_ and 07_ and replaced it with the variable "Jacques_type", because both these variables do exactly the same thing (track J's level and unit type as he enters the scenario). It turns out this structure is used in almost every file in the second half of the campaign.

Here's the structure as it is found in 08_ (I have edited out bits of unrelated code):

Code: Select all

    [event]
        name=start
        {CLEAR_VARIABLE transition}
        {STORE_UNIT_VAR id=Jacques type Jacques_type}
        [switch]
            variable=Jacques_type
            [case]
                value=Thief
                [set_variable]
                    name=transition
                    value=1
                [/set_variable]
                [message]
                    message= _ "Some text..."
                [/message]
                [modify_unit]
                    [filter]
                        id=Jacques
                    [/filter]
                    name= _ "Fierce Jacques"
                    advances_to=Sand Trapper
                    profile=portraits/jacques2.png
                [/modify_unit]
            [/case]
            [case]
                value=Sand Trapper
                [set_variable]
                    name=transition
                    value=2
                [/set_variable]
                [message]
                    message= _ "Some text..."
                [/message]
                [modify_unit]
                    [filter]
                        id=Jacques
                    [/filter]
                    name= _ "Fierce Jacques"
                    advances_to=Battle Commander
                    profile=portraits/jacques2.png
                [/modify_unit]
            [/case]
            [else]
                [transform_unit]
                    id=Jacques
                    transform_to=Battle Commander
                [/transform_unit]
                [modify_unit]
                    [filter]
                        id=Jacques
                    [/filter]
                    name= _ "Fierce Jacques"
                    profile=portraits/jacques2.png
                    hitpoints=64
                [/modify_unit]
                [message]
                    message= _ "Some text..."
                [/message]
            [/else]
        [/switch]
        {CLEAR_VARIABLE Jacques_type}
    [/event]

    ...

    [event]
        name=post_advance
        [filter]
            id=Jacques
        [/filter]
        [switch]
            variable=transition
            [case]
                value=2 #was ST now BC
                [message]
                    message= _ "Some text..."
                [/message]
                [set_variable]
                    name=transition
                    add=1
                [/set_variable]
            [/case]
            [case]
                value=1 # was T now ST
                [message]
                    message= _ "Some text..."
                [/message]
                [set_variable]
                    name=transition
                    add=1
                [/set_variable]
                {MODIFY_UNIT id=Jacques advances_to (Battle Commander)}
            [/case]
        [/switch]
    [/event]
1) I want to replace the "transition" variable with the"Jacque_type" variable throughout. Currently both these vars are initialized and cleared in every non-conversation-only scenario from 05_ onward. But "Jacques_type" could be created in 05_ and only updated after a unit advance (in the "post_advance" event) or a "transformation". It would not be cleared until scenario 15_. I have checked the save files and the variable is persistent and this seems to work. Is there a reason not to do this?

2) What happens in the "start" event [switch] varies. In the code above the cases where J is either T or ST just reset his advance path. The "else" will apply only if he is already a Sand Ranger and it doesn't reset his path but actually transforms him instantly to Battle Commander. The code also points to a name change and a portrait.
a) The portrait (in this particular code above from 08_) is the one showing J with a bow and a sword. The portrait changes ought to happen when he picks up Gronar's bow at the end of 04_ (easiest place to put it is in the 05_ "prestart" event) and then again when he is given Popper's sword at the end of 07_ (easiest to put it in 08_ "prestart" event): it shouldn't need to be mentioned again after that.
b) The name changes here reflect the name changes made in the "side" tags. I finally figured out that's why the {MODIFY_UNIT id=Jacques name _"XXX Jacques"} macros are in some "prestart" events. Apparently whatever name is defined in the side tags doesn't take effect until the next scenario loads (except scenario 01_ seems to be treated differently), so the names as they are defined in the "side" tags all lag behind by one scenario (as near as I can tell). In any event, these name modifications are not made in many of the later files and can be safely removed from this section of code, I think, along with the portrait pointers.
All that raises a separate issue of how the "name" and "profile" keys work in the "side" tag and whether the code can be streamlined even further by using them. It doesn't make sense to me to define a name in the "side" tag and then have to implement it separately in "prestart", but that seems to be the way it works. Not sure what to do about it and if you can shed some light or have an opinion that would be great. My two cents for now: either put the name for J in the "side" tags one file sooner than we want it to appear, or add "modify name" code to each affected file in the "prestart" event (it is currently used only sporadically).

Also note that in 06_ and 07_ J is defined as a "Sand Trapper" in the "side" tag, then in 08_ we return to defining him as a "Thief". I haven't noticed that this has any effect, just a disconnect between what's in the tag and what shows up in the game.

3) In some cases the code varies from this basic pattern. In 13_Following_Destiny (where J goes home) some messages were simply missing so I wrote new ones for that scenario. In a few of the other scenarios (for example 11_), there is a case for J=Thief and for J=Sand Trapper and no case for J=Sand Ranger (but perhaps every case is not needed in every scenario: see below).
Here's what I am minimally recommending:

Code: Select all

    [event]
        name="prestart"
        {STORE_UNIT_VAR id=Jacques type Jacques_type} #05_ only; cleared in 15_

    ...

    [event]
        name=start
        [switch]
            variable=Jacques_type
            [case]
                value=Thief
                {MODIFY_UNIT id=Jacques advances_to (Sand Trapper)}
                [message]
                    message= _ "Some text..."
                [/message]
            [/case]
            [case]
                value=Sand Trapper
                {MODIFY_UNIT id=Jacques advances_to (Battle Commander)}
                [message]
                    message= _ "Some text..."
                [/message]
            [/case]
            [case]
                value=Sand Ranger
                {TRANSFORM_UNIT id=Jacques (Battle Commander)}
	             {STORE_UNIT_VAR id=Jacques type Jacques_type}
                [message]
                    message= _ "Some text..."
                [/message]
            [/case]
        [/switch]
    [/event]

    ...

    [event]
        name="post_advance"
        [filter]
            id="Jacques"
        [/filter]
        [switch]
            variable="Jacques_type"
            [case]
                value="Thief" # was T now ST
                {MODIFY_UNIT id=Jacques advances_to (Battle Commander)}
                [message]
                    message= _ "Some text..."
                [/message]
            [/case]
            [case]
                value="Sand Trapper" # was ST now BC
                [message]
                    message= _ "Some text..."
                [/message]
            [/case]
        [/switch]
        {STORE_UNIT_VAR id=Jacques type Jacques_type}
    [/event]
Also, 07_ only checks if he is a Thief, because the player only gets a message when he changes kind, not level. If he's already a Sand Trapper and advances to Sand Ranger nothing happens (this can only happen in 05_ or 07_). But the way it's written now it looks like he can advance to Rogue in 07_ (instead of ST) because the game doesn't seem to remember from one scenario to the next that the path has been changed. So a similar "modify_unit/advances_to" needs to be added to "start" in 07_ or the R =>ST =>BC case needs to be handled in 08_.

Finally, J is given 64 hit points when he is "transformed" to Battle Commander. That is the number of hit points defined for BC in the unit def file. I did a simple test, and it seems the game does get that number from the unit definition file on a unit transformation, so we could take that line out.

It is very hard to test this code. J needs to be each type he can be in each scenario… I wasted some time trying to figure out a way to edit the save files to quickly change his type or level before I realized I can just add "transform_unit" tags to prestart—doh! Now I can make J anything I want and modify his experience so he'll level after his first encounter, so testing should go a little quicker. Even so it's a lot to test thoroughly and will take some time. Please let me know if you think I'm on track with all this.

I'm uploading the set 08_-16_, but they are very dirty files, with lots of code turned off instead of removed, some extra code put in for testing and some things (like the war drums) still broken. I will keep working on all that, but I want to get the story in your hands because, if you accept the story changes so far, I can strip comments (original lines and story change justifications) from the files to make them much easier to work with.
Attachments
A_Rough_Life-8-16.zip
Second half, very dirty, but the story is intact.
(82.42 KiB) Downloaded 389 times
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Once again, sorry for the delay. But when real life gets in the way, there's not much else that one can do. :(
Jamie wrote:Thanks, but that is the package I have.
At this point, I have to wave a white flag and tell you to ask someone else that has a Mac, like Alarantalara or mattsc. However, I'll run wmllint on my own, so it won't be much of an issue, as I already stated.
Jamie wrote:1) I want to replace the "transition" variable with the"Jacque_type" variable throughout.
There isn't any peculiar reason, other than me not attempting to fix a code that already worked. I'll try your suggestion.
Jamie wrote:All that raises a separate issue of how the "name" and "profile" keys work in the "side" tag and whether the code can be streamlined even further by using them.
These two keys work exactly like in the [unit] tag. However, if there is already a unit with canrecruit=yes, this leader is used and the keys are ignored instead. Theoretically we could place a {SIDE_1} macro in the utils directory and use it in every scenario, but probably wmllint will complain about a missing side 1 in scenario.
Jamie wrote:3) In some cases the code varies from this basic pattern.
Another idea that I had: maybe it could be worth picking that code and (since it appears in different scenarios) turning it into a macro. I'll have to spend some time testing it to see if this will be a good solution, though.
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

Elvish_Hunter wrote:
when real life gets in the way, there's not much else that one can do. :(
Well, life is for living, and gaming and coding are only a very small part of that. No need to apologize. I've got plenty to keep me busy. As you'll see I went ahead and made clean files. After asking you about it, I realized I can have as many different copies as I want or need. I can see where version control might get to be a problem on large programming projects, but for me? :D

Done:
(These are not all the additional changes, but a few worth mentioning. (See change log for more detail.)
Added a change log to the campaign directory (to get them out of the scenario files). I made a lot of changes to the files (to 11_ particularly). I also added a local music directory to fix the war drum issue in 07_ and touched some (but not all) of the unit definition files, the macro file and main.cfg. There's probably more in the change log than is desirable to have in there. I hope it's not too cluttered.

Wrote a bit of background, some of which might fit into the campaign description (it's far too much and too dry to simply use, but bits of it perhaps). It is stored in 01_. Proposed background:
In the time of Black-Eye Karun's legacy, the orcs grew very organized and bold and developed a vast network of slavers that visited every coast in an attempt to fund the orc empire. Sometime in the YW 845, one of these slavers happend along a stretch of cost along the western edge of the peninsula forming the Bay of Pearls. This peninsula was a desolate place compared to the bustling center of Wesnoth, off the busy trade routes, where a small population of humans scrabbled for a meager existence: a perfect target for orc slavers. The tiny village of Mosh is situated in this backwater, near enough to the sea for it's villagers to be familiar with it and to have some knowledge of boats. But being too far inland to get a living from the sea, the villagers scratched in the rocky soil to grow their poor crops and became themselves hard and mean. Smugglers worked the coast and the area was rife with bandits and ruffians. On the other side of the world, four hundred years before the Golden age of the Kingdom of Wesnoth, a small kingdom arose in a lush and fertile land and, due to a brisk local sea trade, prospered and grew for all of those four hundred years: the small kingdom of Rutuba Pinguiyum. But as Wesnoth reached its peak in peace and prosperity in a Golden Age of expansion, Rutuba Pinguiyum was already in decline, its borders contracting, until, on the death of the ancient king in YW 239, a new and much smaller state took its place: Kythonia. It is here, a little more than six hundred years later, that our story takes place. But it all begins in the tiny village of Mosh.
05_ Re: Q on 1,1 hide/teleport/unhide: if put on 19,18 Q will move! (We already talked about this, but I was pleased to discover a very good reason for what seemed at first to be an odd bit of code. Still learning!)

Added a #textdomain to main.cfg —it doesn't seem to matter to play but mainline campaigns all have it

Also made some macros for some death events (and promotions). There is still a lot of repeated text in the files and I could do a lot more of this, but I am ambivalent about it (I was just playing around really when I decided to do it). I don't like having to edit the same line over and over (even if it is just cut and paste). But I also don't like not having all the text in one place. What do you think?
Elvish_Hunter wrote:
These two keys work exactly like in the [unit] tag. However, if there is already a unit with canrecruit=yes, this leader is used and the keys are ignored
In 01_ through 05_ J is defined as a Thief. In 06_, 07_ & 09_ he is a Sand Trapper (08_ he is once again T) and in 10_+ he is a Battle Commander. I changed 08_ to ST just to keep the pattern. I don't think any of this matters. If I understand you right, these keys will always be ignored.
Spoiler:
So here's another upload, the whole campaign this time. I removed all but working comments from the files. I consider them clean but not finished (obviously given my post above). Of course, I might have introduced some errors while cleaning them. I am still testing/working/testing etc.
Attachments
A_Rough_Life_clean.zip
Full campaign with clean (mostly uncommented) code. Includes change log. [edit] NB: The shroud was inadvertently left off in 11_. [/edit]
(5.14 MiB) Downloaded 528 times
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Jamie wrote:Added a #textdomain to main.cfg —it doesn't seem to matter to play but mainline campaigns all have it
Thank you for noticing it.
Jamie wrote:I don't like having to edit the same line over and over (even if it is just cut and paste). But I also don't like not having all the text in one place. What do you think?
It's possible to place all the spoken stuff into a utils/dialogues.cfg file, and then call each dialogue as a macro. That's the best solution, if you think that having everything in one place is the best option.
Jamie wrote:Also in 07_ K changes to druid icon when she attacks - lolz. I think all the animations are there for Melime, but for some reason they are not being used.
That's really weird. The file does not contain anything that references the druid unit - no [base_unit], no druid image paths... And when I tested I didn't notice anything. Not even wmlscope pointed anything about it. :hmm:
Jamie wrote:Micro AIs and moving to 1.12
That's on my checklist as well. Maybe it won't be 1.11.2, maybe it will be 1.11.3 or 1.11.4, but this is definitely going to happen. :)
Jamie wrote:I still want to add some daily damage to K as in the Burning Suns (08_ & 09_, maybe 05_).
I remember that fabi planned, some time ago, to modify the desert damage system in UtBS, by relying on [harm_unit] and casting fire damage on day and cold damage at night. For Kyoko won't make much difference because she has 0% resistance to both, but it'll be much simpler to implement than the current system.
Jamie wrote:Passive leaders (esp F & L) is kind of an issue for me; at least they hit back; could they also hit adjacent?
Since passive leaders play cautious, maybe a good idea will be some AI tweaking. Probably this won't require using Lua or [micro_ai], but just removing passive_leader=yes and increasing leader_aggression=.
Jamie wrote:So here's another upload, the whole campaign this time. I removed all but working comments from the files. I consider them clean but not finished (obviously given my post above). Of course, I might have introduced some errors while cleaning them. I am still testing/working/testing etc.
Thanks again for your work. :)
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
Jamie
Posts: 48
Joined: October 30th, 2011, 5:08 pm

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jamie »

Elvish_Hunter wrote:It's possible to place all the spoken stuff into a utils/dialogues.cfg file, and then call each dialogue as a macro. That's the best solution, if you think that having everything in one place is the best option.
I think a compromise. I have moved the story elements to "utils/story.cfg", but I think the non-story dialog should stay where it is. The code is not so complex that it's hard to follow with the dialog mixed in, and there is enough going on in some of the events that is not dialog to make extracting the dialog tedious to contemplate. It sounds like you don't have a strong preference either way.
Elvish_Hunter wrote:That's really weird. The file does not contain anything that references the druid unit - no [base_unit], no druid image paths... And when I tested I didn't notice anything. Not even wmlscope pointed anything about it. :hmm:
I doubled checked the untouched original campaign to make sure it's not something I introduced. It is throughout, not just in 07_. Whenever she attacks, she changes briefly, then changes back after. It is not very noticeable, and I only picked it up because I was playing 07_ over and over again trying to make sure K wouldn't say a certain line that had been assigned to "second_unit" (and I kept getting the fix wrong). When she attacks R there is a bit of a lag (a lot going on with his mods and then a really long four breath attacks response) so she hangs out there as a druid for a little longer than usual and I was seeing it over and over before it finally registered.
Elvish_Hunter wrote:I remember that fabi planned, some time ago, to modify the desert damage system in UtBS, by relying on [harm_unit] ... it'll be much simpler to implement than the current system.
I am working on this right now, and having some success, but haven't yet figured out how to nullify the healing from adjacent healers. fabi is doing something much more ambitious, checking every unit on the map against their locations. We only have one unit to deal with (Kyoko) and it doesn't matter where she is on the map (except for villages) so what I've got already is much simpler. I am not re-using much of the original code, but I am studying it. [harm_unit] sounds like a great solution, but there are currently no docs for it. Has it already been implemented or is it on the "coming soon" list? [edit] Oops, I spoke too soon. There is no link in the full reference, but there is an entry in the wiki. This is great! I will use it! [/edit]
Elvish_Hunter wrote:Since passive leaders play cautious, maybe a good idea will be some AI tweaking. Probably this won't require using Lua or [micro_ai], but just removing passive_leader=yes and increasing leader_aggression=.
Well, it's a game balance issue, and I really don't play well enough to make balance judgements.
Spoiler:
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Elvish_Hunter »

Jamie wrote:It sounds like you don't have a strong preference either way
That's true. I worked with both systems, so for me it doesn't matter much. :)
Jamie wrote:I doubled checked the untouched original campaign to make sure it's not something I introduced.
You know, there are some things that may cause this issue. One of them may be another campaign or MP era that, due to some bugs, accidentally alters the animation. What other add-ons do you have installed? In any case, you can try removing all the other add-ons (by cutting them and placing them into another directory) and see if the problem shows up again.
Jamie wrote:[harm_unit] sounds like a great solution, but there are currently no docs for it. Has it already been implemented or is it on the "coming soon" list? [edit] Oops, I spoke too soon. There is no link in the full reference, but there is an entry in the wiki. This is great! I will use it! [/edit]
Are you talking about the page at http://wiki.wesnoth.org/AlphabeticalWML ? If yes, it seems like that page is in dire need of an update: there are several tags missing, like [harm_unit], [modify_unit], [set_global_variable], instead of [petrify] there is an entry for [stone]... Use the WML Tags column at http://wiki.wesnoth.org/ReferenceWML instead.
Jamie wrote:I just remember reading something about immobilizing a unit by increasing movement cost. Perhaps remove the passive leader restriction but give the bosses all very high movement costs to keep them in place?
Or we can just reduce their movement. It's pretty simple to do, it doesn't even require to create new unit types:

Code: Select all

#define BOSS_MOVEMENT
    [object]
        silent=yes
        [effect]
            apply_to=movement
            set=3
        [/effect]
    [/object]
#enddef
And, while creating the unit, place said macro inside a [modifications] tag. It's possible to do the same with a direct modification of the max_moves= variable, but applying the object ensures that its effects won't go away after a possible level-up. Of course, if we want to have the boss gain back its original movement, directly modifying max_moves will be a better choice.
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
Jacques_Fol
Posts: 153
Joined: August 16th, 2008, 2:41 am

Re: 1.10 Campaign: A Rough Life - version 1.1.6

Post by Jacques_Fol »

It has been ages since my last visit here, but I remembered and had to check on an old friend. And lo and behold, not only is BfW still going strong (as I suspected), someone has even kept A Rough Life alive, updated and doubtlessly much improved over my original version (as I could hardly have dreamed).

I am humbled by the interest and work gifted to it primarily by Elvish_Hunter, and now also by Jamie. While I am happy and grateful to be kept in memory as the original author, I hope the credits and description make it very clear that ARL would no longer exist and rejuvenate without you guys.

Reading your posts, I am actually quite interested in revisiting the ARL - I may just download it in a little while to test and enjoy all your improvements. Apart from that, I gladly reconfirm that it is in much better hands than mine and I wish you both the best of luck with your future plans.

(And I do apologize for burdening you with a somewhat unfortunate name for the campaign. While it speaks to the content of the campaign, I have come to realize that it may not entice too many users into downloading it just on the power of the name itself. Calling it something a little more epic (The Book of Prophecies) or lyrical (The Rogue and the Princess) would surely guarantee a few more downloads. This is just to say that if you do think of another campaign title you like better, and if such renaming is not frowned upon by the Wesnothian powers-that-be, feel free to go ahead with it.)
Post Reply