Eventi e timer
Questa pagina fa parte di Scrivere script Lua. Le funzioni sono elencate nella guida di riferimento:
events e timer.
Eventi
Section titled “Eventi”Salva questo listener come scripts/common/character_log.lua:
local character_log = {}
character_log.handle = events.on("character_created", function(e) log.info("New character {Name}", e.name)end)
return character_logAggiungi require("common.character_log") al scripts/init.lua esistente, conservando
il resto del codice. Avvia il server oppure inserisci script reload init.lua nella
console del server. Crea un nuovo personaggio dal client: il log della console deve mostrare
New character seguito dal suo nome. Accedere con un personaggio esistente non
genera character_created.
Conserva la tabella restituita dal modulo se vuoi annullare l’iscrizione in seguito. Per rimuovere deliberatamente il listener, esegui questo da codice che richiede lo stesso modulo:
local character_log = require("common.character_log")events.off(character_log.handle) -- returns false when the handle is unknownIl secondo blocco serve alla pulizia; non aggiungerlo alla prima prova, altrimenti il listener verrà rimosso prima che si possa creare un personaggio.
- Ogni handler viene eseguito sul ciclo di gioco come coroutine, quindi può chiamare
wait(). - Gli handler di un evento vengono eseguiti nell’ordine di iscrizione. Iscriversi o annullare l’iscrizione dentro un handler ha effetto dall’evento successivo.
- Ogni handler riceve una propria tabella; modificarla non influisce sugli altri handler.
- Gli eventi sono notifiche: un handler non può annullare o modificare ciò che è accaduto. Un errore in un handler viene segnalato come qualsiasi errore di script, e gli altri handler vengono comunque eseguiti.
- Le iscrizioni appartengono al file che le ha create. Ricaricare o invalidare il file le rimuove, come i suoi timer; arrestare il motore le rimuove tutte.
- Un nome evento sconosciuto genera un errore in
events.on. Il file generatodefinitions.luaelenca i nomi validi come aliasEventName, così gli editor li completano.
Eventi disponibili
Section titled “Eventi disponibili”| Evento | Campi |
|---|---|
character_created |
serial, account_id, name, race e gender (numeri della razza e del genere; gli script non ricevono tabelle enum per essi), map, x, y, z. Generato dopo il salvataggio di un nuovo personaggio e dei suoi oggetti iniziali. |
character_deletion_requested |
serial, account_id, name. Generato dopo che un giocatore chiede di eliminare un personaggio; resta ripristinabile fino alla rimozione. |
character_entered_world |
serial, account_id, name, map, x, y, z. Generato dopo che un personaggio è entrato nel mondo e il login del client è stato completato. |
player_say |
serial, name, text, type. Generato dopo che il personaggio di un giocatore ha detto qualcosa e i giocatori e NPC intorno lo hanno sentito; text è ciò che hanno sentito e type il modo in cui è stato detto, un numero come SpeechType.Yell. Un comando (testo che inizia con un punto) non genera nulla. |
character_left_world |
serial, account_id, name, map, x, y, z. Generato dopo che un personaggio ha lasciato il mondo perché la sessione si è chiusa, una volta tentato il salvataggio. |
player_region_changed |
serial, name, previous, current, map, x, y, z. Generato quando il personaggio di un giocatore cammina o viene teletrasportato da una regione a un’altra, o cambia mappa; previous e current sono i nomi delle regioni, nil fuori da ogni regione, e previous è anche nil quando il personaggio è appena entrato nel mondo |
item_created |
serial, template (nil quando l’oggetto non ne ha uno). Generato quando un nuovo oggetto è entrato nel mondo: creato da uno script, da un venditore, da uno spawn o da un mestiere. Ciò che viene caricato all’avvio o a un login, il resto di una pila divisa, gli oggetti che .decorate posiziona e quelli che un allegato di libro sistema non generano nulla. |
item_deleted |
serial, template. Generato quando un oggetto è stato eliminato: decadimento, unione in una pila, item.delete, l’equipaggiamento di un NPC rimosso. Il logout non genera nulla. |
mobile_created |
serial, template. Generato quando un NPC è stato fatto comparire, anche un animale uscito da una stalla, un animale cavalcato che è stato fatto scendere o un animale legato risollevato dal suo cadavere: la creatura ha ogni volta un nuovo seriale. Gli NPC caricati all’avvio non generano nulla, e una statuetta eterea non crea alcuna creatura. |
mobile_deleted |
serial, template. Generato quando un NPC ha lasciato il mondo: dopo la sua morte, .remove, un animale che è entrato in una stalla, o un animale che è stato montato ed è diventato l’oggetto cavalcatura che il suo cavaliere indossa. Un animale che torna ha un nuovo seriale. |
mobile_died |
serial, killer, corpse (0 se non c’è). Generato quando un giocatore o un NPC è morto; un corpo umano lo genera quando la sua caduta è finita. |
pet_tamed |
serial (l’animale), tamer. Generato quando una creatura è diventata di un giocatore, con pet.tame o .tame. |
craft_succeeded |
actor, craft (l’id del mestiere), item (il seriale di ciò che è stato creato). Generato dallo script di creazione condiviso quando un tentativo è riuscito; un tentativo fallito non genera nulla. |
corpse_carved |
serial (il cadavere), carver, items (quanti oggetti sono stati creati, dentro il cadavere o accanto a esso, con una pila che conta come uno). Generato quando un coltello ha tolto oggetti da un cadavere (carve.corpse); un’operazione che non ha trovato nulla non genera nulla. |
party_invite |
party_id, leader, invitee. Generato quando un capo ha invitato un giocatore; party_id è il numero del gruppo, conservato finché il server è in esecuzione. |
party_joined |
party_id, member. Generato quando un giocatore invitato ha accettato ed è entrato nel gruppo. |
party_left |
party_id, member, reason (left, kicked o logout). Generato quando un membro non è più nel gruppo, anche quello la cui uscita lo scioglie. |
party_disbanded |
party_id, reason (too_small quando restavano meno di due membri, emptied quando è terminato l’ultimo invito dell’unico membro). Generato quando un gruppo non esiste più. |
Gli ultimi dodici sono notifiche del mondo, non di un personaggio: il server pubblica ciascuno solo mentre uno script lo ascolta, quindi un evento a cui nessuno è iscritto costa una ricerca. Gli hook degli script li elencano accanto agli hook e dicono cosa non è stato costruito.
Ogni consegna è un elemento di lavoro del ciclo di gioco. Un riempimento di massa con un ascoltatore su item_created, come uno spawn o uno
script che crea migliaia di oggetti, accoda un elemento di lavoro per ogni oggetto; quando la coda del ciclo è piena gli eventi vengono
scartati, con un avviso nel log.
Pubblicare un evento da C#
Section titled “Pubblicare un evento da C#”Host e plugin pubblicano un evento del bus verso Lua con una registrazione esplicita, prima che il motore si avvii:
container.AddScriptEvent<MyEvent>( "my_event", e => new Dictionary<string, object?> { ["name"] = e.Name, ["amount"] = e.Amount });Il nome deve essere snake_case e univoco, e ogni tipo di evento viene pubblicato una volta. La mappatura viene eseguita sul thread di pubblicazione e deve solo leggere l’evento. Può restituire stringhe, booleani, numeri, enum (inviati come numeri) o null. Una mappatura che fallisce viene registrata nel log, e l’evento viene saltato solo per Lua. Gli eventi pubblicati quando nessuno script è iscritto costano una ricerca e non vengono accodati.
Timer e wait
Section titled “Timer e wait”Tutti i ritardi dei timer e gli argomenti di wait sono in secondi.
timer.after esegue una funzione una volta, timer.every la ripete e timer.cancel arresta entrambi; wait sospende
la coroutine che lo chiama.
Chiama wait da una coroutine pianificata, come una callback di timer, non al livello
principale di init.lua o di un modulo richiesto. Serve un ritardo positivo e finito che
rientri nell’intervallo del timer. Cede la coroutine invece di bloccare il thread.
Ogni occorrenza di un timer ripetuto avvia una coroutine: se una chiama wait per un tempo superiore
all’intervallo di ripetizione, più invocazioni sospese possono coesistere. Annullare
il timer impedisce avvii successivi; non annulla una coroutine già avviata.
Per sequenze che non devono sovrapporsi, usa una callback singola che pianifica la propria
esecuzione successiva solo dopo aver terminato il lavoro.
Creato con ❤️ da Tom
