LUA Error der mir unverständlich ist, g_server.netIsRunning (a nil value)???

  • Hi Leute,


    Ich war dabei ein Skript zu schreiben, das ganze hat eigentlich auch ganz gut geklappt, bis zu dem Punkt wo ich im Skript definieren wollte, wenn ein MP Spiel vorliegt dann mach das.
    Das bekam ich (danke bassaddict) den Tip es mit g_server.netIsRunning bzw mit g_client.netIsRunning zu versuchen.


    Im Sp klappte das ganze auch hervorraggend, mein Skript hat so gearbeitet wie es sollte, da ich am Anfang nur dem Ordner im Mods Ordner hatte, habe ich es dann auch mit "not" versucht, was ja dann das gegenteil wäre, also bei SP Spiel. Auch da funktionierte das ganze wunderbar.
    Meine Abfrage sah so aus:


    [lua]
    if (g_server.netIsRunning or g_client.netIsRunning) then
    erledige meinen Block
    end;
    [/lua]


    Wenn ich alleine in den MP gegangen bin, hat auch noch alles geklappt, keine LOG Fehler. Dann habe ich meinen Tester dazugeholt, er hatte gleiche einen LOG Error, bei ihm hat das Skript weiter den SP Teil ausgeführt und nicht "gemerkt" das es ein MP Spiel war. Der Fehler besagte folgendes:
    Zeile der LUA, "g_server" attemp to index global (a nil value)


    Warum bekomme ich einen LUA Fehler wenn eine variable bekannt ist, bzw in meinem Fall warum soll sie "nil" sein, wenn sie entweder ein true oder false zurückgibt?


    Zumindest wenn ich es selber mit diesem Thema http://planet-ls.de/board/inde…age=Thread&threadID=16992 ausgeben lasse, dann bekomme ich bei g_server die variable netIsRunning als boolean mit false ausgegeben wenn ich im SP bin, wenn ich ein MP erstelle und mir ausgeben lasse dann bekomme ich ein true zurück.


    Oder hat der Fehler damit zu tun das wenn der client es abfragt das es dann nil ist???


    Ich hatte ja noch gedacht das es an meiner Abfrage liegen könnte, also habe ich es auch mal einzeln abgefragt, also:


    [lua]
    if g_server.netIsRunning then
    erledige meinen Block
    end;


    if g_client.netIsRunning then
    erledige meinen Block
    end;


    [/lua]


    Auch so bekam ich den gleichen Fehler.


    Ich habe das ganze mittlerweile gelöst, so das es im SP und MP funktioniert, ob nun als Server oder Client, aber ich möchte das ganze doch gern mal verstehen...

  • Das Problem ist relativ einfach..


    [lua]
    local var = nil;


    if var then
    mach etwas
    end;
    [/lua]


    funktioniert. Wenn var nil ist wird das wie false behandelt und mach etwas wird ignoriert.


    [lua]
    local var = nil;


    if var.x then
    mach etwas
    end;
    [/lua]


    das hingegen funktioniert nicht. Eine Abfrage auf eine Variable innerhalb eines Tables wenn der Table nil ist wirft immer einen Error aus. Liegt weniger am LS sondern mehr an LUA ansich.


    Die korrekte Lösung deines Problems wäre also, zunächst auf g_server ~= nil abfragen, bevor g_server.netIsRunning abgefragt wird.



    [lua]if (g_server ~= nil and g_server .netIsRunning or g_client ~= nil and g_client.netIsRunning) then
    erledige meinen Block
    end;[/lua]



    Hoffe du verstehst was ich sagen will? :)


    LG


    Edit:
    Und zu deiner Grundfrage:

    Zitat

    Warum bekomme ich einen LUA Fehler wenn eine variable bekannt ist, bzw in meinem Fall warum soll sie "nil" sein, wenn sie entweder ein true oder false zurückgibt?


    Zitat

    Oder hat der Fehler damit zu tun das wenn der client es abfragt das es dann nil ist???


    Genau so ist es.

  • Ok, den ersten Teil der Erklärung habe ich verstanden... Danke!


    Aber bei der korrekten Lösung des Problems, das verstehe ich nicht so ganz, zumindest nicht in dem Zusammenhang!
    Wenn ich es so abfragen würde:
    [lua]
    if g_server ~=nil then
    if g_server.netIsRunning then
    erledige meinen Block
    end;
    end;
    [/lua]
    Das würde ich jetzt verstehen, also der Client fragt es ab, bekommt bei der ersten Abfrage ein false zurück, da der table ja nil ist, somit kommt es gar nicht erst zur 2.Abfrage wo ich auf eine variable innerhalb eines nicht existierenden tables zugreife.



    Aber wenn ich die Abfrage so schreibe wie du es erklärt hast, dann tritt ja folgendes ein, zumindest so würde ich es jetzt verstehen:
    [lua]
    if (g_server ~= nil
    [/lua]


    der client fragt ab und bekommt nun ein false zurück... ungleich leer = false, denn g_server ist ja nil.
    aber bekomme ich nun bei der abfrage der Variable mit
    [lua]
    and g_server.netIsRunning or
    [/lua]


    nicht wieder das gleiche Problem? Weil ich doch jetzt wieder auf den nicht existierenden Table zugreifen will?!


    Es würde jetzt ja heißen, wenn ich für g_server ~= nil, ein false bekomme, das LUA dann die abfrage auf einen "false"Table aktzeptiert, bzw mir da auch gleich ein false zurück gibt.


    Habe ich das richtig verstanden???

  • Zitat

    nicht wieder das gleiche Problem? Weil ich doch jetzt wieder auf den nicht existierenden Table zugreifen will?!


    [lua]
    if (x ~= nil and y ~= nil) then
    -- sofern x nil ist wird y gar nicht überprüft.
    end;
    [/lua]
    Bei einer if-Abfrage mit einem and wird sofern die erste Bedingung nicht gegeben ist die zweite erst gar nicht überprüft. Darum sollte das so weit funktionieren ;)



    Zitat

    Es würde jetzt ja heißen, wenn ich für g_server ~= nil, ein false bekomme, das LUA dann die abfrage auf einen "false"Table aktzeptiert, bzw mir da auch gleich ein false zurück gibt.


    Wenn du damit das da meinst:
    [lua]
    if (g_server and g_server.netIsRunning or g_client and g_client.netIsRunning) then
    erledige meinen Block
    end;[/lua]


    Auch das sollte funktionieren.


    LG


  • Das war jetzt mein Fehler, ein kleiner Denkfehler. Hatte mich gefragt warum es mit der korrekten Lösung funktioniert, und dabei gedacht, das es an der ersten Bedingung(g_server ~=nil) liegt, das ich bei der 2. Bedingung (g_server.netIsRunning) keinen Log Fehler bekomme. Es liegt ja auch an der ersten Bedingung, aber mein Gedanke ging dahin, das ich mir gedacht habe, wenn g_server ~=nil, nun ein false zurück gibt, das das der Grund ist, warum ich bei g_server.netIsRunning keinen LOG Fehler kriege.



    Dabei ist es ja im Grunde logisch das es geht, wie du nochmal gesagt hast, das wenn bei einer if-Abfrage mit "and" die erste Bedingung ein false zurück gibt, wird die 2. nicht mehr geprüft. Gibt ja keinen Grund warum ich die 2.Bedingung noch prüfen soll, wenn eine bereits ein false zurück gibt. Und da lag mein Fehler, das habe ich nicht bedacht, und mich deshalb gefragt warum es mit den g_server ~=nil and g_server.netIsRunning ohne Log Fehler geht.
    Aber wenn g_server ~=nil schon false ist, liest LUA ja die Abfrage nach einer Variable aus einem "nicht existierenden table" gar nicht mehr, somit kann es ja keinen LOG Fehler geben.


    Der rest ist somit auch klar. Und sogar verstanden.



    Danke für deine Erklärungen und deine Hilfe, nimmst dir echt immer viel Zeit um ausführliche Erklärungen zu liefern, finde ich echt Spitze!
    Danke!!! :thumbup:

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!