GML, How do I save what room i'm in to .ini? - save

I was learning basic saving/loading for an adventure game and came across this error:
I started out simple with just saving X and Y positions with the player along with the room they're currently in.
ini_open("save.ini");
ini_write_string("Player", "Room", room);
ini_write_real("Player", "X", oPlayer.x);
ini_write_real("Player", "Y", oPlayer.y);
ini_close();
However, it throws an error as soon as I try to save.
FATAL ERROR in
action number 1
of Step Event0
for object pauseMenu:
ini_write_string argument 3 incorrect type (0) expecting a String (YYGS)
at gml_Script_ini_save (line 5) - ini_write_string("Player", "Room", room);
Is there something I'm doing wrong with saving the room, or do I have to go about it a different way?

room is a number, not a string
ini_open("save.ini");
ini_write_string("Player", "Room", room_get_name(room));
ini_write_real("Player", "X", oPlayer.x);
ini_write_real("Player", "Y", oPlayer.y);
ini_close();
For back transform you should use asset_get_index. Something like this:
ini_open("save.ini");
var r_name = ini_read_string("Player", "Room", "");
global.startx = ini_read_real("Player", "X", 0);
global.starty = ini_read_real("Player", "Y", 0);
ini_close();
if r_name == "" or (global.startx == 0 and global.starty == 0)
{
room_goto(r_level1); // first room
}
else
{
var r = asset_get_index(r_name);
if r != -1 and asset_get_type(r_name) == asset_room
room_goto(r);
}
(I don't know, need you these extra checks really or not)

Related

Can't find a way to save a table of data

I have been working on a survival game base on "Booga Booga" but i cant seem to find out how to load player data on the game. The data im trying to load is saved in the for loop that follows:
module.SaveData = function (player, DT)
local data_saved = {}
local setData = player.inventory.Inv:GetChildren()
for i, v in pairs(setData) do
table.insert(data_saved, {[v] = {
value = v.Value,
name = v.Name
}})
end
Data_Store:SetAsync(player.UserId, data_saved)
end
I've done multiple things to attempt to solve this problem
I've tried load with http service
I've already attempted loading the raw table
and I've tried to use a global data store instead
here is my code that loads the data as of now:
game.Players.PlayerAdded:Connect(function(plr)
CF.PlayerInventorySetup(plr) -- not relavent
p = plr -- not relavent
local PD =require(game.ServerScriptService.DataHandler)
local plrdata =PD.FetchData(plr)
for i, v in pairs(plrdata) do -- this is what im having trouble with
if not plr.inventory.Inv:FindFirstChild(v) then
local newint = Instance.new("NumberValue")
newint.Name = v.name -- the ouput says: string expected, got nil
newint.Value = v.value --
newint.Parent = plr.inventory.Inv
end
end
end)
I actually don't know wtf to do.
Before we talk about a solution, let's talk about what's happening when you save the data. Let's say for example, your inventory is a list of NumberValues like this :
Fish (value of 3)
Iron (value of 10)
Grass (value of 8)
Your FetchData function expects that the saved player data is formatted like this :
{
{ value = 3, name = "Fish" },
{ value = 10, name = "Iron" },
{ value = 8, name = "Grass" },
}
However, the result of the loop in the SaveData function would be this :
{
{ Fish(NumberValue) = { value=3, name="Fish" }},
{ Iron(NumberValue) = { value=10, name="Iron" }},
{ Grass(NumberValue) = { value=8, name="Grass" }},
}
On every step of the loop, you are pushing a new dictionary into the data_saved table.
The FetchData function expects that dictionary to have keys for "name" and "value". But, you've pushed that data one layer deeper, so those keys don't exist where the FetchData code expects them to and it throws errors.
So to fix your issue in the SetData function, remove the outer layer of that table, and just use the raw data.
table.insert(data_saved, {
value = v.Value,
name = v.Name
})

How to return a table with string keyed key value pairs from a lua script to node js?

I have a lua script. I am running from node.js and my script is returning a lua table with key value pairs in it like { '1': 15, '2': 35 }. In node I am getting an empty array. However if I return arrayName['1']. It gives me proper value 15. What am I doing wrong here. I am using node_redis client for node to redis. Diffrent files are given below.
Lua Script - groupBy.lua
local db = "";
local table = "students";
local groupBy = "class";
local aggregate = "marks";
local a = {};
local marksGroupedByClass = {};
for i = 1, 4 do
local dataArr = redis.call("hgetall", db..table..":"..i);
local dataObj = {};
for i = 1, #dataArr, 2 do
dataObj[dataArr[i]] = dataArr[i+1];
end
if a[dataObj["class"]] then
a[dataObj["class"]] = a[dataObj["class"]] + dataObj["marks"]
else
a[dataObj["class"]] = dataObj["marks"]
end
end
return a['2']; -- This returns proper value 35
-- return a; This returns empty array to node
node file - luaExec.js
let fs = require('fs');
let redis = require('redis');
let client = redis.createClient();
client.on("error", cb);
function cb(err) {
console.log("Error " + err);
}
client.eval(fs.readFileSync('groupBy.lua'), 0, (err, replies) => {
if(err) cb(err);
console.log(replies);
})
client.quit();
I saved my data with this script - saveStudentData.lua
redis.call("hmset","students:1", "name", "A", "class", 1, "marks", 5 );
redis.call("hmset","students:2", "name", "B", "class", 1, "marks", 10 );
redis.call("hmset","students:3", "name", "C", "class", 2, "marks", 15 );
redis.call("hmset","students:4", "name", "D", "class", 2, "marks", 20 );
TL;DR you can't.
Redis has no support for a key-value type of response (although there are talks of changing that in the next version of the protocol RESP3).
Thus, returning an associative array from Lua (a table with kv pairs) results in an empty array as you've found out. What you'll need to do is flatten it, e.g.:
...
local reply = {} for k, v in pairs(a) do
table.insert(reply, k)
table.insert(reply, v)
end
return reply
Or simply prepare a flattened in the preceding loop. Lastly, your client will have to be aware of this format and recompose the object from it, should that be needed.

Find Words in entire module

I have skip list contains an ADC, FIFO, DAC, FILO etc.
I want to know whether these words are used in the entire module or not .if used in the module should return the unused words.
I have a program but it is taking too much time to execute.
Please help me with this.
Here is the code :
Skip Search_In_Entire_Module(Skip List)
{
int sKey = 0
Skip sList = create()
string data = ""
string objText1
Object obj
for data in List do
{
int var_count = 0
for obj in m do
{
objText1 = obj."Object Text"
if objText1!=null then
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
Buffer buf = create()
buf = objText1
int index = 0
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
delete(buf)
}
}
if (var_count ==0)
{
put(sList,sKey,data)
sKey++
}
}
return sList
}
Unused_Terminolody_Data = Search_In_Entire_Module(Terminology_Data)
Just wondering: why is this in a while loop?
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
I would instead just do:
index = contains ( buf, data )
if ( index == -1 ) {
var_count++
}
buf = ""
I would also not keep deleting and recreating the buffer. Create the buffer up where you create the object variable, then set it equal to "" to clear it, then delete it at the end of the program.
Let me know if this helps!
Balthos makes good points, and I think there's a little more you could do. My adaptation of your function follows. Points to note:
I implemented Balthos's suggestions (above) of taking out the
'while' loop, and buffer creation/deletion.
I changed the function signature. Given that Skip lists are passed
by reference, and must be created and deleted outside the function
it's syntactically confusing (to me, anyway) to return them from a
function. So, I pass both skip lists (terms we're seeking, terms not
found) in as function parameters. Please excuse me changing variable
names - it helped me to understand what was going on more quickly.
There's no need to put the Object Text in a string - this is
relatively slow and consumes memory that will not be freed until
DOORS exits. So, I put the Object Text in a buffer earlier in the
function, and search that. The 'if (!null bufObjText)' at my line 34
is equivalent to your 'objText1!=null'. If you prefer, 'if
(bufObjText != null)' does the same.
The conditional 'if (var_count ==0)' is redundant - I moved it's
functions into an earlier 'if' block (my line 40).
I moved the tests for deleted, table, row and cell objects up, so
that they occur before we take the time to fill a buffer with object
text - so that's only done if necessary.
Item 2 probably isn't going to have a performance impact, but the others will. The only quesiton is, how large?
Please let us know if this improves the running time over what you currently have. I don't have a sufficiently large set of sample data to make meaningful comparisons with your code.
Module modCurrent = current
Skip skUnused_Terminology_Data = create
Skip skSeeking_Terminology_Data = create()
put (skSeeking_Terminology_Data, 0, "SPONG")
put (skSeeking_Terminology_Data, 1, "DoD")
void Search_In_Entire_Module(Skip skTermsSought, skTermsNotFound)
{
Object obj
Buffer bufObjText = create()
int intSkipKey = 0
int index = 0
string strSkipData = ""
for strSkipData in skTermsSought do
{
int var_count = 0
bool blFoundTerm = false
for obj in modCurrent do
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
bufObjText = obj."Object Text"
if (!null bufObjText) then
{
Regexp re = regexp2 strSkipData
blFoundTerm = search (re, bufObjText, 0)
if ( blFoundTerm ) {
put(skUnused_Terminology_Data, intSkipKey, strSkipData)
intSkipKey++
}
bufObjText = ""
}
}
delete (bufObjText)
}
Search_In_Entire_Module (skSeeking_Terminology_Data, skUnused_Terminology_Data)
string strNotFound
for strNotFound in skUnused_Terminology_Data do
{
print strNotFound "\n"
}
delete skUnused_Terminology_Data
delete skSeeking_Terminology_Data

Lua return index of a nested table

This is my first attempt to use Lua tables and I'm getting on with it quite well. I'm struggling with one thing though, heres (a small sample of) my table as it currently stands:
objects = {
["1/1/1"] = { tl = 1, startVal = 1, stopVal = 0 },
["1/1/2"] = { tl = 11, startVal = 1, stopVal = 0 },
["1/1/3"] = { tl = 22, startVal = 1, stopVal = 0 },
["1/1/4"] = { tl = 33, startVal = 1, stopVal = 0 },
}
The typical operation of this is that I use the "1/1/1" values as a lookup to the inner tables and then use those values in various functions. This all works well. Now, I need to go the other way, say I have tl = 22 coming in, I want to return the top value ("1/1/3" in this case).
I think I need to do something with the inpairs I keep seeing on the web but I'm struggling to implement. Any help would be massively appreciated.
You can't use ipairs because your table is an associated array not a sequence, so you have to use pairs. Also, there is no search function builtin to Lua, so you have to loop over all items yourself, looking for the right field value:
function findTL(tbl)
for key, data in pairs(tbl) do
if data.tl == tlSearch then
return key
end
end
end
local key = findTL(objects, 22)
If you want something a tad more object-oriented you could do this:
objects.findTL = findTL -- ok because first arg is the table to search
local key = objects:findTL(22)
isn't it better to take the value directly?
objects.1/1/1.tl
I don't know if it will work also with slashes, but if not, you may replace it by 'x' for example. Then it will be:
objects.1x1x1.tl

Lua error: string expected, got nil --- bad argument #2

It is a script in Lua for a game in Corona SDK. At first the (Old code) was very inefficient and I had to manually create each math problem manually, with the (New code) with the help from someone on SO I got that.
In the console I get this error now:
line 93: local questionText = display.newText(questionGroup, questions[currentQuestion].question, 0,0, chalkfFont, 34 )
game.lua:93: bad argument #2 to 'newText' (string expected, got nil)
--mathQuestions.lua (Old code)
local M = {}
M["times"] = {
{
question="6 x 5", --The question.
answers={"30", "11", "29", "20"}, --Array of possible answers.
answer=1 --Which one from the above array is the correct answer.
},
}
return M
--mathQuestions.lua (New code)
local rnd = function (x) return math.random(1,x) end
M.times = {}
local numQuestions = 10 -- how many questions in your database
for i=1,numQuestions do
local obj =
{
left=math.random(1,10),
right=math.random(1,10),
answers={rnd(100), rnd(100), rnd(100), rnd(100)},
answerIndex=rnd(4) -- will override answer[answerIndex] later
}
obj.answer = obj.left * obj.right
obj.answers[obj.answerIndex] = obj.answer
M.times[i] = obj
end
Any ideas on what the problem is and how to fix it? Thanks.
Line 93 has "questions[currentQuestion].question": each item in questions table is a table with field "left", "right" etc, but no field "question" which you access in line 93. In your loop where you define questions add a line before "obj.answer =":
obj.question = string.format("%s x %s", left, right)

Resources