KULT Underground

una della più "antiche" e-zine italiane – attiva dal 1994

Quake Editing

6 min read

Quake Editing

Capitolo terzo

Ave, miei prodi! (no, è scritto con la minuscola, non è quello che pensate: la politica non c’entra niente con Kult Underground).
Preparatevi perché questo capitolo terzo è un capitolo cruciale di questa rubrica, perché qui cominceremo ad entrare nel cuore del motore di Quake, e dal cuore prenderemo poi, nei successivi appuntamenti, tutte le strade possibili (del tipo, dal cuore al braccio destro, dal cuore al braccio sinistro, dal cuore alla testa, dal cuore al… così insomma…) fino ad esaurire completamente l’argomento
(…completamente?).

———————————————————————-

Abbiamo parlato nel capitolo precedente di Brush e di Entity, ora vediamo come questi elementi vengono gestiti dal motore stesso di
Quake.
Un livello di Quake viene creato attraverso una serie di strumenti di sviluppo, tre per la precisione, che si occupano ognuno di un singolo aspetto specifico del processo di creazione.

Il file su cui è basata ogni elaborazione di questi tool, è il cosiddetto file “.map”, che è praticamente un file di testo contenente tutte le informazioni sui poligoni e sulle entità che dovranno comporre il nostro livello. Questo è il file di partenza, perché questo è l’unico formato di file comprensibile dai compilatori di
Quake (almeno che io sappia); qualunque livello possibile di qualunque complessità è rappresentabile in un file map, in un modo che ora andremo ad analizzare.

La sintassi del file map ricorda da vicino la programmazione in linguaggio C, perché le entità vengono definite classi, le stringhe sono rappresentate tra doppi apici e i blocchi di informazioni sono delimitati da parentesi graffe. Il tutto in una rappresentazione tutto sommato semplice e lineare, anche perché le uniche rappresentazioni possibili sono sempre e solo quelle due: entità e poligoni.

Ricordate ora cosa abbiamo detto nel capitolo precedente riguardo all’entità globale che contiene tutto ciò che è rappresentato in un singolo livello? Ebbene, ora abbiamo la prova di quanto precedentemente detto: se è vero che tutto l’universo rappresentato è contenuto in un’unica entità, allora un file map contiene in definitiva semplicemente la definizione di questa grande entità, giusto?

Giusto, infatti è proprio così: un file map contiene la definizione della classe globale del livello, che viene chiamata worldspawn.
Ovviamente questa definizione può essere anche molto complessa, perché può contenere un grande numero di sottoentità e poligoni, però in ogni caso la prima cosa che si incontra in un file map (aprendolo ad esempio con un editor di testo) è proprio questa definizione.

———————————————————————-

Vediamo in dettaglio un esempio di file map:

{
“classname” “worldspawn”
“message” “Leggi Kult Underground”
“wad” “gfx/unknown.wad”
{
( 6 2 4 ) ( 6 6 4 ) ( 6 6 6 ) wbrick1_5 0 0 0 1 1
( 8 2 1 ) ( 8 6 6 ) ( 8 6 4 ) wbrick1_5 0 0 0 1 1
( 8 6 1 ) ( 6 6 6 ) ( 6 6 4 ) wbrick1_5 0 0 0 1 1
( 8 2 4 ) ( 6 2 4 ) ( 6 2 6 ) wbrick1_5 0 0 0 1 1
( 8 2 1 ) ( 6 2 6 ) ( 6 6 6 ) wbrick1_5 0 0 0 1 1
( 8 6 4 ) ( 6 6 4 ) ( 6 2 4 ) wbrick1_5 0 0 0 1 1
}

}

Innanzitutto si nota, come già detto, che tutti i blocchi (siano essi definizioni di entità o poligoni) sono delimitati da parentesi graffe, così come le stringhe sono delimitate da doppi apici.

La prima cosa che si incontra è appunto la definizione della classe worldspawn: come ogni classe che si rispetti, la definizione di questa
è appunto un elenco di valori accoppiati in cui si incontra a sinistra il nome della proprietà della classe e a destra il valore assegnato.
In questo esempio, la proprietà classname ha valore worldspawn, la proprietà message ha valore Leggi Kult Underground e wad ha valore gfx/unknown.wad: fin qui è una normale definizione di classe.

La differenza rispetto ad un normale linguaggio è che qui non ci sono metodi, solo proprietà. Tutto quello che non è definizione della proprietà di una classe è definizione di un brush: infatti sotto all’elenco delle proprietà di worldspawn notiamo una serie di valori numerici raggruppati in vario modo che altro non è se non la definizione di un poligono.

Se la definizione di un poligono è inserita all’interno della definizione di un’entità, allora quel brush è associato proprio all’entità che lo contiene (ricordate che un’entità può essere astratta, come una luce, ma anche concreta, come una porta automatica). Infatti nell’esempio il poligono è definito dentro alla classe worldspawn, per cui è parte dell’entità globale worldspawn.

———————————————————————-

Soffermiamoci ora alla definizione di un brush:

{
( 6 2 4 ) ( 6 6 4 ) ( 6 6 6 ) wbrick1_5 0 0 0 1 1

( 8 6 4 ) ( 6 6 4 ) ( 6 2 4 ) wbrick1_5 0 0 0 1 1
}

Ogni linea è la definizione di una faccia, e l’insieme delle facce
(quindi tutte le linee comprese tra parentesi graffe) è ovviamente la definizione del poligono (o brush). Per ogni faccia c’è un terzetto di terzine di valori numerici racchiusi da parentesi tonde: questi sono i tre punti che identificano il piano contenente la faccia in questione; questi tre punti sono seguiti poi dal nome (questa volta senza doppi apici) della texture che andrà applicato a quella faccia, seguito a sua volta da una serie di valori che indicano appunto come la tessitura verrà applicata a quella faccia.

In dettaglio, i primi due valori indicano l’offset del bitmap rispetto alla griglia standard di texturizzazione (ne parleremo in seguito), il terzo indica la rotazione attorno ad un ipotetico asse perpendicolare alla faccia definita e gli ultimi due valori indicano la scalatura rispettivamente in ascissa e in ordinata della
“decalcomania” (ovviamente 1 è il moltiplicatore che indica dimensione originale).

Ovviamente, quello che è più rilevante ai fini della definizione di un poligono sono i tre punti di ogni faccia, il texture è un passaggio successivo, anche se fondamentale, che però può essere anche lasciato così com’è: non è necessario sempre scalare, ruotare, e disallineare una texture per realizzare un livello di qualità, più importante è l’idea che sta alla base e la costruzione architettonica in sé.

Qui mi ricollego a quello che prima ho definito “griglia standard di texturizzazione”: normalmente, i texture vengono applicati sulle superfici secondo criteri prestabiliti dall’engine di Quake, seguendo le linee guida di una griglia precalcolata di 64×64 pixel.
Questo significa che se io sviluppo un livello seguendo una metrica a multipli di 64, otterrò sempre e comunque texture allineate, perché dove finisce una faccia, finisce anche la linea guida della griglia, quindi la texture è sempre “perfettamente incollata”: per questo ho detto che non è sempre necessario, utilizzando un po’ di sale di zucca, impazzire ad allineare ruotare e scalare i bitmap, basta un criterio rigido ma allo stesso tempo efficiente.

E’ ovvio che 64 pixel sono tanti come massimo dettaglio di un livello, ed è per questo che è lasciata al designer la libertà di manipolare l’applicazione delle tessiture come meglio crede ed al massimo dettaglio possibile (cioè la singola faccia). Se nasce l’esigenza di creare strutture complesse ad un dettaglio superiore basterà sfruttare queste possibilità per allineare manualmente le decal come meglio si crede, ma è una cosa che non sarà da fare sempre, permettendo quindi di disegnare grandi ambienti in un tempo ragionevolmente ridotto.

A questo punto molti di voi diranno: Ok, tutto questo è molto bello, c’è la libertà di manipolare le texture, c’è la libertà di utilizzare poligoni composti da un qualunque numero di facce, c’è la linearità e tutto sommato semplicità del file map, ma io, se voglio fare un livello di Quake, lo faccio con un editor di testo???

Ovviamente no! Ci sono tantissimi editor in circolazione (leggi
Internet) che permettono di disegnare ed editare in maniera più o meno intuitiva tutti i vari elementi a disposizione, senza preoccuparsi quindi della struttura che sta sotto; è importante però capire che ogni editor, di qualunque tipo e a qualunque livello, deve per forza esportare i file in formato map per farli poi digerire alle utility di compilazione.

L’editor infatti in realtà serve solo per evitare di scrivere appunto un intero livello di Quake nel bloc-notes di Windows, semplicemente perché l’editor stesso scrive il file map al posto nostro, mentre noi usiamo lui (con sprezzante sadismo) per semplificarci la vita e sfogare quindi meglio la nostra creatività.

———————————————————————-

Questo è tutto quanto basta per poter dire -io so cos’è un file map, e tu no!-; nel prossimo capitolo analizzeremo più in dettaglio le entità principali che costituiscono un livello standard e parleremo anche dei tre tool che servono per compilare il livello finale, quello che poi potremo provare in Quake.

Nel frattempo, digerite per bene quello che abbiamo trattato finora perché non è proprio banalissimo, e soprattutto non è facile da spiegare in una serie di articoli: Quake è una tecnologia, è un argomento piuttosto vasto anche se non è certo paragonabile ad un sistema operativo multipiattaforma, per questo non sarà mai possibile trattare proprio tutto, ci vorrebbe troppo tempo e troppo spazio (e ci vorrebbe anche un reddito per questo), ma farò tutto il possibile per introdurvi all’argomento ed indirizzarvi ad eventuali fonti di approfondimento successive.

Con queste parole, una lacrimuccia che sgorga dalla sacca congiuntivale destra, e lo sguardo fiero e determinato che guarda lontano, un po’ più su dell’orizzonte, vi saluto e vi rimando al prossimo capitolo di Quake Editing… (sigh!)

Fabrizio Cerfogli

Commenta