Latest Posts

Topic: Scenarios: File I/O

Nordfriese
Avatar
Topic Opener
Joined: 2017-01-17, 18:07
Posts: 1928
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2018-04-10, 18:29

I have started scripting the third scenario for the frisians campaign. One feature I really want to use (planning ahead here) is saving campaign data between scenarios. Basically, I want to save certain information to a file when scenario #3 is completed, and read it from there in scenario #4 to reuse it.

In normal Lua, I can write to a file like this:

function save_campaign_data(filename, text)
   local file = io.open(filename, "w")
   for i,t in ipairs(text) do
      file:write(t)
   end
   file:close()
end

If I need to create the directory structure first, I can use

os.execute("mkdir " .. name)

(this works on Linux and Windows; is there an OS where it won´t?)

When using those in a Widelands scenario script, the game crashes with

Trying to run: map:scripting/init.lua: Scenario not started: Game data error: lua: [../src/scripting/lua_errors.cc:22] [string "scripting/campaign_data.lua"]:51: attempt to index a nil value (global 'os')

The same message also appears for "… (global 'io')".

So my first question is: What do I need to do to use "io" and "os" in my Widelands scenario?

My second question is: Campaign data files should be stored in the Widelands home directory, e.g. in "~/.widelands/campaigns/frisians/fri03.wcd". How can I get the path to the home directory in the script?


Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16
Posts: 2646
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2018-04-10, 21:44

Hello Nordfriese,

Nice idea I could use that in the empire campaign as well. So I am very interested in the solution as well.

Off topic: I would like to continue my tests on balancing the frisians, would you mind if I would create a branch to improve that? Would you support this issue?


Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 20:48
Posts: 2433
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2018-04-10, 23:50

Nordfriese wrote:

I have started scripting the third scenario for the frisians campaign. One feature I really want to use (planning ahead here) is saving campaign data between scenarios. Basically, I want to save certain information to a file when scenario #3 is completed, and read it from there in scenario #4 to reuse it.

This is a nice idea i think face-smile.png

Have you tried to explicit load the os and io module with require?

require os
require io

My second question is: Campaign data files should be stored in the Widelands home directory, e.g. in "~/.widelands/campaigns/frisians/fri03.wcd". How can I get the path to the home directory in the script?

I guess this needs a new LUA function for the widelands API...


Fight simulator for Widelands:
https://wide-fighter.netlify.app/

Top Quote
Nordfriese
Avatar
Topic Opener
Joined: 2017-01-17, 18:07
Posts: 1928
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2018-04-11, 18:55

kaputtnik wrote:

Nordfriese wrote:

I have started scripting the third scenario for the frisians campaign. One feature I really want to use (planning ahead here) is saving campaign data between scenarios. Basically, I want to save certain information to a file when scenario #3 is completed, and read it from there in scenario #4 to reuse it.

This is a nice idea i think face-smile.png

Thanks face-smile.png

Have you tried to explicit load the os and io module with require?

~~~~ require os require io ~~~~

Using require causes this error:

Trying to run: map:scripting/init.lua: Scenario not started: Game data error: lua: [../src/scripting/lua_errors.cc:22] [../src/scripting/lua_errors.cc:22] [string "scripting/campaign_data.lua"]:1: attempt to call a nil value (global 'require')

Strange that Widelands Lua doesn´t know such a basic function.
But I found in the code that src/scripting/lua_interface.cc seems to load some modules in LuaInterface::LuaInterface(), e.g.

    open_lua_library(lua_state_, LUA_MATHLIBNAME, luaopen_math, true);

Perhaps I only need to add:

    open_lua_library(lua_state_, LUA_OSLIBNAME, luaopen_os, true);
    open_lua_library(lua_state_, LUA_IOLIBNAME, luaopen_io, true);

Will try to compile with this, perhaps it solves the problem…

My second question is: Campaign data files should be stored in the Widelands home directory, e.g. in "~/.widelands/campaigns/frisians/fri03.wcd". How can I get the path to the home directory in the script?

I guess this needs a new LUA function for the widelands API...

Should I open a bug report?

hessenfarmer wrote:

Off topic: I would like to continue my tests on balancing the frisians, would you mind if I would create a branch to improve that?

Please do face-smile.png


Top Quote
GunChleoc
Avatar
Joined: 2013-10-07, 15:56
Posts: 3324
Ranking
One Elder of Players
Location: RenderedRect
Posted at: 2018-04-11, 19:55

You'll need to open a bug report for this. It won't happen for Build 20 though, so best start with writing your scenario without it first, leaving room to add the alternative thread.

I have been reworking how campaign visibility works: https://code.launchpad.net/~widelands-dev/widelands/campaignselect_box. In that branch, rather than marking which scenarios are visible, I am marking which scenarios have been solved. The configuration then defines prerequisite scenarios for each scenario/campaign. So, if all you need is to have a branch, you could set scenario 3a as solved or scenario 3b, and then show the matching follow-up scenario. Implementing that in the branch should be fairly easy.

As for accessing the os functions, we need to expose those in our Lua interface in C++ first. This is a security measure.

Maybe we should discuss this some more first before opening the bug reports, so that we'll be clear on what needs implementing.


Busy indexing nil values

Top Quote
Nordfriese
Avatar
Topic Opener
Joined: 2017-01-17, 18:07
Posts: 1928
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2018-04-11, 22:10

Either I misunderstand what you mean, or you mean something different than me.
I´m not talking about a fork in the storyline, such as "if X happens during scenario #2, then launch scenario #3a, else the completetly different scenario #3b".
I mean saving information about certain observations during the scenario which will be saved like sort-of variables. A simple example: When mission 3 is complete, it saves the number of logs in stock to a file; when mission 4 starts, it reads this number from the file and gives the player as many logs as he had at the end of the last scenario. I don´t see how your branch can help with that.

As for accessing the os functions, we need to expose those in our Lua interface in C++ first. This is a security measure.

Only os or io as well?

By the way, I uploaded the scenario draft to a branch now. The I/O stuff is in https://bazaar.launchpad.net/~widelands-dev/widelands/scenario-fri-03/view/head:/data/scripting/campaign_data.lua


Top Quote
GunChleoc
Avatar
Joined: 2013-10-07, 15:56
Posts: 3324
Ranking
One Elder of Players
Location: RenderedRect
Posted at: 2018-04-12, 10:06

From a quick look at the branch, seems like you've got it covered now. Let us know if you get stuck again.

One thing you should keep in mind is that that campaign_data could be deleted manually by the user, so you should make sure to have a fallback in case the file doesn't exist, without forcing the player to completely replay the previous scenario. At the very least, there should be no crashes when the file doesn't exist.

Also, data like this can have a great impact on how easy or hard the follow-up scenario gets - I remember reading about this problem on the Battle for Wesnoth forums. There is a danger of good players getting bored, and novice players getting overwhelmed.

Battle for Wesnoth wrote:

Balancing gold becomes difficult in campaigns because of gold carryover, which often has the exact opposite of the desired effect: struggling players will start with less gold (usually the minimum), while accomplished players will have a sizable treasury. This severely limits the designer's ability to balance the scenario by adjusting the player's starting gold.

https://wiki.wesnoth.org/BuildingScenariosBalancing#Player.27s_starting_gold

Nordfriese wrote:

Only os or io as well?

Basically, anything you can't access, so I guess so.

Edited: 2018-04-12, 10:07

Busy indexing nil values

Top Quote
WorldSavior
Avatar
Joined: 2016-10-15, 04:10
Posts: 2091
OS: Linux
Version: Recent tournament version
Ranking
One Elder of Players
Location: Germany
Posted at: 2018-04-16, 21:39

Nordfriese wrote:

hessenfarmer wrote:

Off topic: I would like to continue my tests on balancing the frisians, would you mind if I would create a branch to improve that?

Please do face-smile.png

Good idea face-smile.png


Wanted to save the world, then I got widetracked

Top Quote
Nordfriese
Avatar
Topic Opener
Joined: 2017-01-17, 18:07
Posts: 1928
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2018-04-17, 20:49

GunChleoc wrote:

Also, data like this can have a great impact on how easy or hard the follow-up scenario gets - I remember reading about this problem on the Battle for Wesnoth forums. There is a danger of good players getting bored, and novice players getting overwhelmed.

Yes, allowing good players to keep wares, supersoldiers or other advantages can be a problem. The frisian campaign is marked as highest difficulty level though, so it should be clear that the later scenarios tend to be very hard for beginners anyway.

But I was thinking exactly the other way around regarding balancing. Without revealing too much of the storyline I can say I´ve already planned ahead as far as a major battle in mission 5:
Scenario 3 will be partly an economy race where the player must recruit and train many soldiers in limited time. In #4, the player will get soldiers as a "reward" for fulfilling optional objectives. In #5, the player will get all the soldiers "collected" in #3 and #4.

I´m going to prevent major balancing problems by setting the difficulty for mission 4 in accordance with the military power the player has after #3. That is, players who train lots of soldiers in #3 will get very few in #4 and vice versa. Therefore, good and less good players should start #5 with approximately the same strength. The hardest thing here is finetuning the difficulty levels in #4, but I´ll take care of this when #3 is complete. This method adds more depth and variety to the campaign while compensating more or less (!) the problems with soldier carry-over.


Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16
Posts: 2646
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2018-04-17, 23:47

Just a short question as I don't have time to test it myself: are your changes working? Does the interface work correctly in your branch? That would give us so much more options in campaign design. I have some really good ideas for the empire as well. Thanks for bringing these ideas up.


Top Quote