Friday, December 28, 2007

Sole


Una galassia ha tante stelle.
Tantissime.
Una delle cose che non ho mai sopportato degli space-sim nati dopo frontier è la loro scarsa credibilità nelle dimensioni.
Galassie con 400 stelle, distanze tra oggetti in un sistema solare misurate in km, ma dico son 100 km da qui a Bologna, un aereo copre quella distanza in 6 minuti, un banalissimo space shuttle ci mette 18 secondi, mi vien la claustrofobia!!
Il buon Braben invece ha voluto far le cose fatte per bene, ricordiamolo: nei primi anni novanta e in 600kb, e sia il numero di stelle che le distanze nel suo gioco sono verosimili. Si ragiona in anni luce, e le stelle sono MILIONI.

Ora, partiamo da questo secondo aspetto.. Un milione di stelle (per ipotesi), un nome per ciascuna di esse diciamo di 10 caratteri, occorre quindi memorizzare un milione di nomi. E se 10 megabytes oggi possono essere una cifra tutto sommato modesta, non ho di certo nessuna intenzione di scrivere 10 miloni di caratteri.
E' molto piu' furbo farli generare automaticamente. L'idea è quella di costruire un array di 30 stringhe, ciascun elemento contiene una sillaba. "se", "lo", "kar", ecc... Per ogni stella vado a pescare 1,2 oppure 3 sillabe, prese a caso da questo elenco, e le concateno.
Si ottengono nomi tutto sommato plausibili "sekar" "karlose" ecc..
Rimane il problema di memorizzare un milione di nomi... ma non ce n'e' bisogno. Infatti il generatore di numeri casuali ha una proprieta', chiamata seme, per la quale, a parita' di seme, genera sempre la stessa sequenza di numeri casuali... cosi' se imposto il seme 44, posso avere una sequenza del tipo 1,42,9,58,7,22,... se imposto il seme = 2, potrei ottenere 95, 24, 4, 0, 11,...
ma se lo reimposto di nuovo a 44, otterro' nuovamente 1,42,9,58,7,22,...
Percio', una volta divisa la galassia in una griglia, e chiamato ciascun elemento della griglia "settore", ho che ogni settore ha una coordinata x,y che lo identifica univocamente. Se dalla coppia x,y ricavo un numero, ad esempio s = x+100*y, sono sicuro che:

  1. il numero s è unico per ogni settore della galassia
  2. il numero s può essere utilizzato per impostare il seme per la generazione dei numeri casuali
Morale: dividendo la galassia in settori (un rettangolo verde della griglia che vedete in foto), riesco al volo a decidere il nome della stella, senza bisogno di memorizzarlo. Basta impostare il seme e andare a pescare con il generatore di numeri casuali tra le sillabe.

Come potete vedere la cosa funziona, ed è un sistema che mi permette di gestire decine di milardi di miliardi di stelle in pochi kappa. L'unico problema (per ora) è la generazione a volte di nomi duplicati. Ma di questo parleremo un'altra volta: si' ho in mente una soluzione

Wednesday, December 19, 2007

Scrivere

Uno dei problemi da affrontare, arrivati a questo punto, è la visualizzazione del nome della stella, accanto al corrispondente "pallino".
Detta così sembra una cosa piuttosto banale, si tratta pur sempre dell'antichissimo "print", ma quando si lavora in 3D nulla è scontato.
Inanzitutto cosa usare? Sprites? Qualche altra funzione che ancora non conosco?
Per ora ho intrapreso la strada degli sprites, che però si stanno dimostrando inaspettatamente avidi di risorse. O sbaglio qualcosa io oppure, un pc che comunque riesce a far girare bene half life 2, entra in crisi non appena il numero di sprites super qualche centinaio. Ci dovrò studiare: siamo d'accordo che comunque il tutto viaggia ancora abbondantemente sopra i 100fps (la soglia di allarme e' a 30 fps), ma si tratta pur sempre di linee e pallini, non di Crysis.
In ogni caso, una volta scelta la strada degli sprites rimane un secondo problema: gli sprites lavorano in 3D, hanno la loro brava terna x,y,z, e subiscono il comportamento di tutti gli oggetti tridimensionali, in particolare uno sprites lontano apparirà piccolo, mentre uno sprite vicino sarà molto piu' grande.
Ora, se questo va bene per i pallini, non va affatto bene per le scritte. Probabilmente avere una stella vicina con pallino molto grande e relativo nome stampato bello grande avrà anche un suo bel impatto drammatico, ma risulta poco pratico, anche perchè, viceversa, le stelle lontane avranno un pallino piccolo, ed un nome microscopico, di difficile lettura. E questa è una mappa, non un rendering fotorealistico.
Non va bene.. ma per fortuna directx sono corse in mio aiuto: esiste una funzione in grado di trasformare una coordinata tridimensionale in bidimensionale, ovvero dato un punto x,y,z dello spazio virtuale, mi restituisce l'ascissa e l'ordinata dello schermo ove apparirà il punto, così richiamandola per ogni stella, mi restituisce il punto esatto dello schermo dove dovrei mettere il nome corrispondete.
A sto punto diventa finalmente un banale print, o meglio un "print at", se qualcuno si ricorda il basic.

Il risultato lo potete vedere qui sotto (click sull'immagine per ingrandire). Non ho ancora implementato la generazione dei nomi delle stelle, quindi per ora tutte si chiamano allo stesso modo. Però funziona, e ruotare la mappa finalmente comincia ad essere quantomeno gradevole.

Ma 200 fps non vanno bene, occorre capire cosa si mangia tutto quel tempo.

Monday, December 17, 2007

"Mio Dio, è pieno di stelle!"


Lo sviluppo, coi tempi che mi son concessi, procede. E finalmente la mappa inizia ad avere un aspetto...che ricorda quello di una mappa :)
Ogni stella ha le proprie coordinate all'interno di un quadrato della mappa, ovviamente X,Y,Z.
Se Y>0, la stella è posizionata sopra il piano verde che rappresenta l'ipotetico piano su cui e' appoggiato il centro della galassia, se Y<0 ovviamente la stella sta sotto.
Per rendere piu' leggibile la griglia, ho deciso (per ora) di colorare di bianco le stelle che stan sopra, e di giallo quelle che stan sotto, vedete da voi che gia' con 50 stelle il rischio di far confusione non e' nullo.
Tecnicamente ogni stella rappresentata è composta da due elementi: una linea verticale che ne denota la distanza dal piano, e un pallino che come detto, oltre ad aiutare la visualizzazione, dovra' in futuro rappresentare anche il tipo di stella. L'asticella e' una banale linea DX9, mentre il pallino è stato implementato usando uno sprite, per risparmiare triangoli (ogni sprite usa 2 triangoli, se avessi dovuto usare una sfera, sarebbero stati molti di più, che moltiplicato per il numero di stelle presenti beh...).
Il problema degli sprites però è che hanno uno spessore nullo, così il rischio è che, ruotando la mappa, si assottiglino fino a sparire per venir divorati dal back culling.
Così ho risolto ruotando ciascun sprite di un angolo esattamente opposto a quello della telecamera, così da far sì che in qualsiasi modo io pongo la telecamera, questi appaiono sempre perfettamente frontali, dando l'illusione che non siano piatti ma piuttosto sfere.
I problemi più grossi li ho avuti cercando di far convivere sprites e linee, a causa senz'altro della mia poca esperienza con dx9, ma direi che adesso ci siamo.
Un'altra funzione che avranno gli sprite-pallino sarà quella di contenere il nome del sistema. Infatti accanto a ciascuna stella voglio farne comparire il nome.
Una cosa alla volta.
Il prossimo passo sarà comunque noioso: devo far pulizia nelle classi, ora che ho qualcosa che sta in piedi è imperativo far sì che lo scheletro sia pulito e ben documentato, altrimenti non solo sarà il gioco che non vedrà mai la luce, ma anche che finirà molto presto nel trashcan.
Voglio anche approfittarne per far un po' di ottimizzazione. D'accordo che siamo sui 500fps, ma son pur sempre solo 50 sprites, e io sono della vecchia guardia, quelli che vivono per ottimizzare :)

Sunday, December 16, 2007

Per far un viaggio ci vuol la mappa


Da qualche parte si deve pur cominciare, e dal momento che non sono ancora molto pratico di utilizzo delle directx, ho deciso di iniziare lo sviluppo dalla creazione della mappa.
Una cosa che mi ha sempre affascinato dei lavori di Braben è l'enorme densità di informazioni che questi contengono. Il suo primo Elite conteneva 8 galassie da 255 stelle ciascuna in meno di 48 kb, e Frontier l'intera via lattea in 600Kb.
Chiaramente usa dei trucchi: le stelle sono generate casualmente, così come i nomi, ma il tutto è fatto intelligentemente, così i nomi, le locazioni, le caratteristiche, son tutte casuali ma sempre uguali tra diverse partite, dando l'illusione cosi' che vi sia veramente una galassia memorizzata in pochi kappa.
E questa sarà la strada che prenderò anch'io. L'idea è quella di prendere un'immagine di una galassia, converirla in bianco e nero. Ogni pixel rappresenta diciamo di 50 anni luce quadrati, in base all'intensita' del "bianco" di ciascun pixel, corrisponde una densita' di stelle all'interno di quel quadrato 50x50. Piu' e' bianco e piu' stelle ci saranno, e viceversa.
Il risultato e' quindi quello di una griglia di 800x600 quadrati, pieni ciascuno di un numero casuale di stelle, che comunque rispecchia l'andamento della galassia.
E' cosi' anche l'occasione per mostrarvi il primo screenshot di quel che sto facendo.
Ovviamente il tutto e' moooolto grezzo e va comunque considerata più come una curiosità che altro.

Ah, due parole sui tool usati, visto che mi è stato chiesto.
Per lo sviluppo ho scelto il C++, in quanto linguaggio veloce, nessuna "schifezza" interpretata o macchine virtuali che mal si sposano con l'inevitabile ricerca di ottimizzazione.
Come compilatore ho scelto il Visual C++ Express 2005. Non sono soddisfattissimo dal tool, ma e' freeware, e gran parte degli esempi che si trovano in giro sono studiati proprio per questa IDE.
Se avete qualche suggerimento però dite pure! :)
Per il modeling 3D il davvero eccellente Blender, infine Paint Shop Pro per il disegno 2D

Friday, December 14, 2007

Tau Ceti


E' il nome del mio progetto, che deriva da quello di una stella a 12 anni luce dalla terra, ma anche da un vecchio videogame uscito su zx spectrum, uno dei primi esempi di grafica 3D con effetti di illuminazione.
Non avendo la presunzione di riuscire a creare un gioco dal nulla, la mia idea e' quella di provare a creare un emulo di Frontier, uno space-sim uscito su Amiga tanti anni fa, e che a suo modo e' tutt'ora ineguagliato in tanti aspetti che (spero!) affrontero' con l'andare avanti di questa mia avventura.
Questo gioco, scritto da David Braben, oltre a riprodurre in soli 600 Kb una galassia con non so nemmeno quante decine di migliaia di stelle, conteneva elementi innovativi quali una fisica davvero credibile (moto inerziale, moto orbitale), la possibilita' di scendere su pianeti, la dinamicita' di tutti gli oggetti che componevano l'universo (i pianeti ad esempio orbitavano attorno alle stelle, e le lune attorno ai pianeti), spazio e tempo credibili (non piu' astronavi che fanno mezza galassia in 10 secondi netti, ne' pianeti distanti tra loro 100 km), oltre ad una grafica per quei tempi sbalorditiva.
Molti space-sim son usciti da allora, la grafica e' ovviamente tutt'altra cosa, eppure nulla e' riuscito piu' a stupirmi come quei 600 kappa, percio' se devo copiare voglio farlo dal migliore, e il migliore e' Frontier.

Per lo sviluppo ho deciso di iniziare occupandomi della mappa, ma di questo parlero' nel prossimo post.

Prefazione

Correva non ricordo che anno, tra il 1980 e 1990 comunque.
C'era una rivista, allora, che si occupava di videogiochi, dal nome Zzap!, molti di voi la ricorderanno senz'altro. E tra le tante recensioni e rubriche, una in particolare mi affascinò: il diario di Andrew Braybrook, che raccontava numero dopo numero la creazione di un suo videogioco.
Mi ipnotizzava leggere i suoi progressi giorno per giorno, quella serie di pixel quasi a casaccio che piano piano prendevano sempre piu' forma. Talmente mi affascinarono che fu li' che nacque il mio sogno: scrivere un videogioco.
Son passati piu' di 20 anni, e il sogno non si e' mai realizzato. Nel frattempo il mondo dei videogiochi e' cambiato, non e' piu' pensabile per un singolo capellone realizzare il capolavoro passando le notti in bianco sull'assembler, lo sapete meglio di me.
Ecco quindi il perchè della descrizione di questo blog.

Ma le circostanze vogliono che in questo periodo stia studiando per hobby il funzionamento delle directx di Mircosoft, e quale miglior occasione per far uscire dal cassetto quel vecchio sogno?

Non so dove andro' a finire, puo' darsi che paradossalmente sia stato oggi l'ultimo giorno in cui ho messo mano a Tau Ceti, ma non mi pongo ne' limiti ne obblighi, dove arrivo arrivo, e nel frattempo ho piacere di condividere con voi le cose che imparero' giorno per giorno.

Ed avere pure io il mio piccolo diario, come Braybrook.