11 KiB
Wired Bug Audit
1. Scopo
Questo documento raccoglie i potenziali bug, le aree fragili e le incoerenze architetturali emerse durante l’analisi del sistema wired.
Non tutti i punti qui sotto sono bug già riprodotti al 100%, ma sono:
- problemi già visti in comportamento reale
- incongruenze tra runtime e UI
- zone del codice che possono generare regressioni o risultati non deterministici
Riferimenti principali:
Arcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredManager.javaArcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredEngine.javaArcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.javaArcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredMoveCarryHelper.javaArcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired
2. Sintesi Priorità
| Priorità | Tema | Stato |
|---|---|---|
| Alta | context variabili esposto ma non implementato davvero |
Incoerenza forte |
| Alta | Doppio runtime (WiredManager vs WiredHandler) |
Rischio architetturale |
| Alta | Ordine effect non sempre garantito senza extra esplicito | Rischio comportamentale |
| Alta | Path movimento legacy può ancora far trapelare update intermedi | Già osservato in stanza |
| Media | Tick a 50ms ma delay wired in step da 500ms |
Semantica non uniforme |
| Media | Polling realtime :wired a 50ms |
Rischio carico/runtime noise |
| Media | click furni ora immediato, queue/cancel svuotati |
Possibile regressione |
| Media | Semantica timestamp variabili non uniforme tra target types | Possibile confusione logica |
3. Audit Dettagliato
3.1 context nelle variabili: esposto ma non veramente supportato
- Gravità: Alta
- Confidenza: Alta
- Area: effetti/condizioni/extras variabili
Problema
Nel layout e in parte della serializzazione compare il target context, ma in più punti il runtime lo rifiuta esplicitamente oppure restituisce direttamente false.
Questo crea una situazione pericolosa:
- il designer pensa che la feature esista
- il box si salva o si configura parzialmente
- ma poi in esecuzione non produce il comportamento atteso
Evidenze
WiredEffectGiveVariable.java:197- il save rifiuta
TARGET_CONTEXT
- il save rifiuta
WiredConditionVariableValueMatch.java:181case TARGET_CONTEXT -> false
WiredConditionVariableAgeMatch.java:146case TARGET_CONTEXT -> false
WiredExtraTextOutputVariable.java:83- il save rifiuta
TARGET_CONTEXT
- il save rifiuta
Impatto pratico
- stack che sembrano validi in UI ma non funzionano a runtime
- falsi negativi nelle condition variabili
- placeholder testuali variabili non disponibili quando l’utente si aspetta il target context
Fix suggerito
Scegliere una direzione netta:
- o implementare davvero
contextin tutti i flow variabili - o rimuoverlo completamente da UI, save e runtime finché non è pronto
La seconda opzione è la più sicura nel breve periodo.
3.2 Doppio runtime wired ancora presente
- Gravità: Alta
- Confidenza: Alta
- Area: architettura core
Problema
WiredManager dichiara di essere il runtime esclusivo e tratta i vecchi flag come sola compatibilità, ma WiredHandler esiste ancora con entrypoint completi e logica propria.
Evidenze
WiredManager.java:136- warning esplicito:
wired.engine.enabled / wired.engine.exclusive are now compatibility-only flags
- warning esplicito:
WiredManager.java:174isEnabled()dipende solo dall’inizializzazione del manager
WiredManager.java:182isExclusive()ritorna sempretrue
WiredHandler.java:63- entrypoint legacy completo
handle(...)
- entrypoint legacy completo
WiredHandler.java:114- supporto separato per
handleCustomTrigger(...)
- supporto separato per
Impatto pratico
Se qualunque pezzo di codice, plugin o path legacy entra ancora in WiredHandler, si possono avere:
- ordine effect diverso
- scheduling delay diverso
- condition flow diverso
- diagnostica/monitor non coerente col nuovo engine
Fix suggerito
- definire un solo entrypoint runtime ufficiale
- se
WiredHandlerdeve restare, trasformarlo in adapter minimo che inoltra sempre al nuovo engine - aggiungere log o metriche per rilevare qualsiasi ingresso nel path legacy
3.3 Ordine degli effect non sempre deterministico senza wf_xtra_exec_in_order
- Gravità: Alta
- Confidenza: Alta
- Area: esecuzione stack
Problema
Nel path legacy, l’ordinamento stabile viene applicato chiaramente solo in presenza di wf_xtra_exec_in_order oppure in casi specifici (unseen).
Negli altri casi, l’ordine si appoggia alla collezione che arriva dal runtime.
Evidenze
WiredHandler.java:224- rileva
hasExtraExecuteInOrder
- rileva
WiredHandler.java:230- ordina con
WiredExecutionOrderUtil.sort(effects)solo in alcuni casi
- ordina con
WiredHandler.java:249- usa direttamente
effectListin ordered mode
- usa direttamente
Impatto pratico
Stack come:
move_rotate+match_to_sshottoggle+resetgive_var+change_var_val
possono produrre risultati diversi se si assume implicitamente un ordine che il runtime non promette davvero.
Fix suggerito
- decidere se l’ordine stack deve essere sempre stabile di default
- in alternativa, mantenere la regola attuale ma documentarla in modo molto esplicito
- se si lascia la regola attuale, conviene segnalare in UI che l’ordine è garantito solo con
wf_xtra_exec_in_order
3.4 Il path movimento legacy può ancora far vedere movimenti intermedi
- Gravità: Alta
- Confidenza: Alta
- Area: movement pipeline
Problema
Il helper legacy di movimento usa ancora un fallback che, se il collector non è attivo, invia subito FloorItemOnRollerComposer.
Questo può far trapelare al client uno stato intermedio che in teoria avrebbe dovuto essere nascosto da batching o restore finale.
Evidenze
WiredMoveCarryHelper.java:163- metodo
moveFurniLegacy(...)
- metodo
WiredMoveCarryHelper.java:179- usa il collector se disponibile
WiredMoveCarryHelper.java:196- fallback diretto a
FloorItemOnRollerComposer
- fallback diretto a
Impatto pratico
È coerente con il tipo di bug già visto:
- oggetto che “si vede muovere”
- poi viene riportato nello stato corretto
- ma il client ha già ricevuto un update intermedio
Fix suggerito
- evitare qualsiasi composer diretto nel path legacy quando la logica wired moderna è attiva
- centralizzare tutti i movement update in un unico collector finale
- aggiungere test specifici per:
move_rotate+match_to_sshot- stacked move effects nello stesso tick
3.5 Tick a 50ms, ma delay wired ancora a step da 500ms
- Gravità: Media
- Confidenza: Alta
- Area: semantica temporale
Problema
Il sistema oggi ha due granularità temporali diverse:
- repeaters / tickables a
50ms - delay wired classico a
delay * 500ms
Evidenze
WiredTickService.java:48DEFAULT_TICK_INTERVAL_MS = 50
WiredTickService.java:175scheduleAtFixedRate(...)
WiredEngine.java:753long delayMs = delay * 500L
WiredHandler.java:369- stesso schema
delay * 500L
- stesso schema
Impatto pratico
Non è per forza un bug, ma può creare:
- aspettative sbagliate nel builder dei wired
- sensazione di desync tra repeater e delay
- stack “velocissimi” su tick ma “grossolani” sugli effect ritardati
Fix suggerito
- o si accetta questa doppia semantica e la si documenta ovunque
- o si introduce una nuova famiglia di delay high-resolution separata dal delay classico
3.6 :wired realtime a 50ms può diventare rumoroso/pesante
- Gravità: Media
- Confidenza: Alta
- Area: tooling monitor/inspection
Problema
Le request di monitor e variabili ora sono rate-limitate a 50ms.
Evidenze
WiredMonitorRequestEvent.java:39return 50
WiredUserVariablesRequestEvent.java:20return 50
Impatto pratico
Su una stanza attiva o con più client staff aperti:
- carico rete maggiore
- più rumore sul server
- rischio di mascherare problemi reali con spam di refresh
Fix suggerito
- spostare dove possibile a push/event driven
- lasciare
50mssolo per il minimo indispensabile - differenziare:
- monitor heavy/debug
- inspection live
- variables snapshot
3.7 click furni ora è immediato: queue/cancel svuotati
- Gravità: Media
- Confidenza: Alta
- Area: eventi click furni
Problema
La queue dei click furni è stata semplificata: ora il click parte subito, e il cancel path è vuoto.
Evidenze
WiredManager.java:274queueUserClicksFurni(...)chiama subitotriggerUserClicksFurni(...)
WiredManager.java:282cancelPendingUserClicksFurni(...)non fa nulla
Impatto pratico
Se qualche comportamento vecchio dipendeva da:
- debounce
- cancel
- click differito
ora può cambiare senza che il mapping sia ovvio.
Fix suggerito
- decidere se il comportamento immediato è quello definitivo
- se sì, documentarlo come breaking behavior
- se no, reintrodurre una queue reale con semantica esplicita
3.8 Semantica timestamp variabili non uniforme tra target type
- Gravità: Media
- Confidenza: Media
- Area: sistema variabili
Problema
Le variabili utente e furni hanno senso come “assegnazione con creation/update time”, mentre le room/global variables hanno soprattutto senso sul solo update time.
Questo può diventare ambiguo quando si usano:
wf_cnd_var_age_match- sorting per creation/update
- UI manage/inspection
Evidenze
WiredConditionVariableAgeMatch.java- il target room/global vive soprattutto come valore di update
- le scelte di prodotto già fatte in
:wiredvanno in questa direzione
Impatto pratico
- il builder può pensare che “tempo di creazione” sulle global sia forte quanto sulle user/furni
- condition o sort possono essere semanticamente strani anche se “funzionano”
Fix suggerito
- trattare esplicitamente
room/globalcomeupdated-only - disabilitare in UI le opzioni che non hanno senso forte
- o documentare in modo molto chiaro la differenza
4. Backlog Consigliato
Ordine suggerito di intervento:
- Chiudere il target
context- o implementarlo davvero
- o toglierlo da UI/save/runtime
- Unificare il runtime
- lasciare un solo entrypoint ufficiale
- Stabilire la regola sull’ordine effect
- default stabile o ordine esplicito con extra
- Chiudere il leak dei movement update legacy
- niente composer fuori collector quando wired moderno è attivo
- Ripensare il realtime di
:wired- spostare il più possibile da polling a push
5. Nota Finale
Il sistema wired attuale è già molto più potente del modello classico, soprattutto per:
- variabili
- signal routing
- selectors avanzati
- monitor
- manage/inspection
Proprio per questo, le zone fragili oggi non sono tanto i box semplici, ma:
- la coesistenza di due runtime
- la semantica temporale
- i movement stack
- le feature variabili ancora “mezze esposte”
Questi sono i punti che più probabilmente spiegano i bug strani o intermittenti.