Scenario script Rescue and related audio files
Rescue scientist from Kraylor Supports any number of player ships simultaneously Different terrain each time the scenario is run With the default settings:
- Runs in 30-60 minutes
- Low to medium difficulty (adjustable with initial parameters)
Uses utility files:
- utils.lua
- place_station_scenario_utility.lua
- cpu_ship_diversification_scenario_utility.lua
- generate_call_sign_scenario_utility.lua
- comms_scenario_utility.lua
Error on launch in master branch/ECS:
scenario_22_rescue.lua:1151: function findClearSpot expects a space object or table as the object in the object list table item index 1, but got a userdata instead
stack traceback:
scenario_22_rescue.lua:1151: in global 'findClearSpot'
scenario_22_rescue.lua:1331: in global 'placeTerrain'
scenario_22_rescue.lua:974: in global 'constructEnvironment'
scenario_22_rescue.lua:56: in function <scenario_22_rescue.lua:43>
init() function failed, not going to call update()
I tried extending SpaceObject checks like
assert(type(item.obj)=="table"
to also check for the userdata type:
assert(type(item.obj)=="table" or type(item.obj)=="userdata"
On starting the scenario and unpausing it, no further error messages are emitted. The briefing voice clip plays and the terrain is generated, but no player entities are created. If I create one manually and join it, I see that the mission had instantly failed.
I need to look at the asserts. Looks like the assumptions made for pre-ECS no longer apply to ECS. I'll try removing the asserts and see what other errors (if any) occur. The asserts were probably put in more to tell me when I passed in the wrong parameters or stored the wrong things in the item list.
The scenario does not create a player ship. If it's still failing instantly when a player ship is spawned then this logic in the update(delta) function is failing:
if delta == 0 then
if deployed_players ~= nil then
for i,dp in ipairs(deployed_players) do
for j,p in ipairs(getActivePlayerShips()) do
if p == dp.p then
dp.name = p:getCallSign()
end
end
end
end
return --because the scenario is paused
end
That seems to be the case. If I unpause the scenario without a playership, it instantly fails, which sounds like the expected behavior.
If I create a playership first and then unpause the scenario, I get errors on attempt to perform arithmetic on a nil value (local 'base_range') and the rest of the script doesn't run:
[ERROR ]: LUA-Error:scenario_22_rescue.lua:1932: attempt to perform arithmetic on a nil value (local 'base_range')
stack traceback:
scenario_22_rescue.lua:3140: in function <scenario_22_rescue.lua:3126>
[WARNING ]: Failed to find glyph in font:0x9
[ERROR ]: LUA-Error:scenario_22_rescue.lua:1932: attempt to perform arithmetic on a nil value (local 'base_range')
stack traceback:
scenario_22_rescue.lua:3140: in function <scenario_22_rescue.lua:3126>
[ERROR ]: LUA-Error:scenario_22_rescue.lua:1932: attempt to perform arithmetic on a nil value (local 'base_range')
stack traceback:
scenario_22_rescue.lua:3140: in function <scenario_22_rescue.lua:3126>
[ERROR ]: LUA-Error:scenario_22_rescue.lua:1932: attempt to perform arithmetic on a nil value (local 'base_range')
stack traceback:
scenario_22_rescue.lua:3140: in function <scenario_22_rescue.lua:3126>
[ERROR ]: LUA-Error:scenario_22_rescue.lua:1932: attempt to perform arithmetic on a nil value (local 'base_range')
stack traceback:
scenario_22_rescue.lua:3140: in function <scenario_22_rescue.lua:3126>
L3140 is the updatePlayerLongRangeSensors() function invoked from update(), where p is passed from getActivePlayerShips().
I see that comms_scenario_utility populates a p.normal_long_range_radar with p:getLongRangeRadarRange(), which should return either self.components.long_range_radar.long_range or 50000 in ECS. So my guess is that getActivePlayerShips() isn't working as expected.
The legacy description of getActivePlayerShips() says it "returns a 1-indexed list of active PlayerSpaceships`. In ECS/master it also appears to return an indexed list of entities with the PlayerControl component. So I'm not sure what the disconnect here is, unless I'm not correctly tracing back how the scenario is finding active playerships.
As best as I can tell, it should be set the local variable base_range on line 1906:
local base_range = p.normal_long_range_radar
It gets this from p.normal_long_range_radar. This value should be set in line 2047:
p.normal_long_range_radar = player_ship_stats[temp_type_name].long_range_radar in function updatePlayerSoftTemplate
temp_type_name (aka template name) is set in the same function on line 2037:
local temp_type_name = p:getTypeName()
player_ship_types is set starting on line 360 in the setGlobals function
If these variables are not set right, I could see where base_range is not set. My first suspect is getTypeName()
I'm learning a lot about Lua userdata this month, at least. ~~It sounds like the script relies on setting arbitrary data in p, but p in ECS is now userdata instead of a table type. So there's a fundamental backward-compatibility issue for legacy-compatible scenarios that usetable features or assign arbitrary properties to them, on entities that are now userdata in ECS.~~
EE handles properties on entity userdata, so that's not it. It's #2602, and GinjaNinja32 fixes it in #2601.
With that patch to fix onNewPlayerShip(), I can load and run the scenario. A few notes from an attempted playthrough:
- The scan probes positioned on space stations prevent the station from being selected for comms. Clicking on the station always targets the scan probe. This makes reputation irrelevant and prevents comms with stations until the probes expire after about 20 minutes.
- If the scan probes are meant to reveal the stations to the player's Relay or facilitate comms, they also didn't work for that.
- It was unclear how the player is meant to locate the station holding the scientist. Comms scripts on stations were default/generic reinforcement and resupply options only, and the scannable entities around the map didn't provide hints. Looking at the scenario script, that doesn't seem to be the intent.
- After docking with the station holding the scientist, which triggered the
switch_to_kraylor"Kraylor have gained control and engaged the docking clamps" event,p:setCanDock(false)had the opposite intended effect. Instead of preventing the player ship from undocking, the player ship was forcibly undocked, and it couldn't dock with that or any other station for the rest of the scenario. The brainstorm_time event never occurs since the player ship is no longer docked, leaving it impossible to complete
The scan probes are only temporarily located on the station. Once you unpause, they should travel off to their destination. They should not end up on top of another station. If they do, that's a problem. The scan probes are more decoration than anything. I can simply remove them if they are not going to work correctly in ECS Starting on line 1682, you can see that when a scan probe is placed,
- the owner is set to one of the stations
- the owner position is the starting position for the probe (s_x, s_y)
- the target is the environment object coordinates (eo_x, eo_y) - where the probe ends up
local station_pool = getStationPool(placement_area)
local owner = tableSelectRandom(station_pool)
local s_x, s_y = owner:getPosition()
object:setLifetime(20*60):setOwner(owner):setTarget(eo_x,eo_y):setPosition(s_x,s_y)
object:onExpiration(probeExpired)
object:onDestruction(probeDestroyed)
object = VisualAsteroid():setPosition(eo_x,eo_y)
If you see generic comms for stations, that's a problem. They should be using the comms utility. Placing a station follows this pattern (line 841):
home_station = placeStation(psx + player_spawn_x, psy + player_spawn_y,"RandomHumanNeutral","Human Navy")
The placeStation function can be found in place_station_scenario_utility.lua (line 33). This function calls pickStation, where the default comms are replaced with the comms in comms_scenario_utility.lua on line 170:
station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station_name):setDescription(station_pool[group][selected_station_name].description)
Instead of a brute force search, the players can contact the station to get information on other stations in the area which leads them to the research station where they are supposed to get the scientist.
I can't do anything about the docking shenanigans. It works fine in legacy
I try to be clear about this in the Discord and should do so here as well, if I bring up ECS-specific issues I don't expect you to solve them in the scenario script. They indicate a backward compatibility break in ECS that needs investigation and potentially a fix in ECS, like #2601/#2602.
probes not moving was a bug in the new API.