|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#61 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
è fantastico!!!
__________________
My gaming placement |
|
|
|
|
#62 | |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 3490
|
Quote:
return *((INT*)(((BYTE*)(&GEngineLoop)) + 14));
__________________
www.biffuz.it | Thou shall not follow the NULL pointer, for chaos and madness await thee at its end. Powered by: M1 @ Sonoma | 7600X @ W11 | C2Q @ XP | P!!! @ W98+BeOS | 286 @ W3.1 | C64 | iP16 | iPad8 | rPi4 | and more... |
|
|
|
|
|
#63 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Fixing bugs, the (very) hard way...
Questa dev'essere leggendaria, nell'ambiente
![]() --- Meet My Dog, Patches There's an old joke that goes something like this: Patient: "Doctor, it hurts when I do this." Doctor: "Then stop doing it." Funny, but are these also wise words when applied to the right situation? Consider the load of pain I found myself in when working on a conversion of a 3D third person shooter from the PC to the original PlayStation. Now, the PS1 has no support for floating point numbers, so we were doing the conversion by basically recompiling the PC code and overloading all floats with fixed point. That actually worked fairly well, but were it fell apart was in collision detection. The level geometry that was supplied to us worked reasonably well in the PC version of the game, but when converted to fixed point, all kinds of seams, T-Junctions and other problems were nudged into existence by the microscopic differences in values between fixed and floats. This problem would manifest itself by the main character (called "Damp") simply falling through those tiny holes, into the abyss below the level. We patched the holes we found, tweaking the geometry until Damp no longer fell through. But then the game went into test at the publisher, and suddenly a flood of "falling off the world" bugs were delivered to us. Every day a fresh batch of locations were found with these little holes that Damp could slip through. We would fix that bit of geometry, then the next day they would send us ten more. This went on for several days. The publisher's test department employed one guy whose only job was to jump around the world for ten hours a day, looking for places he could fall through. The problem here was that the geometry was bad. It was not tight and seamless geometry. It worked on the PC, but not on the PS1, where the fixed point math vastly magnified the problems. The ideal solution was to fix the geometry to make it seamless. However, this was a vast task, impossible to do in the time available with our limited resources, so we were relying on the test department to find the problem areas for us. The problem with that approach was that they never stopped finding them. Every day bought more pain. Every day new variants of the same bug. It seemed like it would never end. Eventually the penny dropped. The real problem was not that the geometry had small holes in it. The problem was that Damp fell through those holes. With that in mind, I was able to code a very quick and simple fix that looked something like: IF (Damp will fall through a hole()) THEN Don't do it The actual code was not really much more complex than that (see Listing 2). Listing 2: Meet My Dog, Patches Codice:
damp_old = damp_loc;
move_damp();
if (NoCollision())
{
damp_loc = damp_old;
}
Well, it shipped eventually. Spurred on by the success of "if A==bad then NOT A", I used this tool to patch several more bugs -- which nearly all had to do with the collision code. Near the end of development the bugs became more and more specific, and the fixes became more and more "Don't do thispreciseandexacthing" (see Listing 3, actual shipped code). Listing 3: Meet My Dog, Patches Codice:
if (damp_aliencoll != old_aliencoll &&
strcmpi("X4DOOR",damp_aliencoll->enemy->ename)==0 &&
StartArena == 6 && damp_loc.y<13370)
{
damp_loc.y = damp_old.y; // don't let damp ever touch the door.. (move away in the x and y)
damp_loc.x = damp_old.x;
damp_aliencoll = NULL; // and say thusly!!!
}
Looking back I find this code quite horrifying. It was patching bugs and not fixing them. Unfortunately the real fix would have been to go and rework the entire game's geometry and collision system specifically with the PS1 fixed point limitations in mind. The schedule was initially aggressive, so we always seemed close to finishing, so the quick patch always won over the comprehensive, expensive fix. But it did not go well. Hundreds of patches were needed, and then the patches themselves started causing problems, so more patches were added to turn off the patches in hyper-specific circumstances. The bugs kept coming, and I kept beating them back with patches. Eventually I won, but at a cost of shipping several months behind schedule, and working 14 hour days for all of those several months. That experience soured me against "the patch." Now I always try to dig right down to the root cause of a bug, even if a simple, and seemingly safe, patch is available. I want my code to be healthy. If you go to the doctor and tell him "it hurts when I do this," then you expect him to find out why it hurts, and to fix that. Your pain and your code's bugs might be symptoms of something far more serious. The moral: Treat your code like you would want a doctor to treat you. - Mick West ---
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 24-07-2013 alle 15:57. |
|
|
|
|
#64 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Divertente!
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
#65 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Colpisco ancora con una short story allora...
--- 10-Tative Code Back at [company X], I think it was near the end of [the project], we had an object in one of the levels that needed to be hidden. We didn't want to re-export the level and we did not use checksum names. So right smack in the middle of the engine code we had something like the following. The game shipped with this in. Codice:
if( level == 10 && object == 56 )
{
HideObject();
}
- Anonymous ---
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
#66 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 3490
|
Ah beh, cose del genere ai programmatori capitano praticamente tutti i giorni
__________________
www.biffuz.it | Thou shall not follow the NULL pointer, for chaos and madness await thee at its end. Powered by: M1 @ Sonoma | 7600X @ W11 | C2Q @ XP | P!!! @ W98+BeOS | 286 @ W3.1 | C64 | iP16 | iPad8 | rPi4 | and more... |
|
|
|
|
#67 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
la classica frase "ma tanto noi ci abbiamo messo le mani e ce lo ricordiamo..."
__________________
My gaming placement |
|
|
|
|
#68 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 3490
|
A volte fanno 'ste cose in librerie condivise che al momento usano solo loro, coinvinti che i progetti precedenti non servano più a nessuno, peccato che poi se lo dimenticano e quando devono fare un altro progetto ne copiano uno vecchio "ma non capisco, prima funzionava!"
__________________
www.biffuz.it | Thou shall not follow the NULL pointer, for chaos and madness await thee at its end. Powered by: M1 @ Sonoma | 7600X @ W11 | C2Q @ XP | P!!! @ W98+BeOS | 286 @ W3.1 | C64 | iP16 | iPad8 | rPi4 | and more... |
|
|
|
|
#69 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Ma ste storielle da dove le prendete? Perchè alcune mi sembrano veramente impossibili che siano successe..
Cioè, se io facessi il programmatore di professione, mi sentirei moralmente a disagio a fare delle cose del genere ( Ok che ci sono delle scadenze da rispettare, però un po' di pianificazione e rigore nello sviluppo di un'applicazione credo siano assolutamente necessarie ).
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
#70 | |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
ho trovato (e scritto) delle porcate assurde che spero nessuno un giorno vada a correggere, per rispettare tempi di consegna e specifiche assurde
__________________
My gaming placement |
|
|
|
|
|
#71 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 3490
|
Io sono uno di quelli a cui dicono sempre "sì fai dei bei programmi, ma potresti evitare la prossima volta e cercare solo di essere più veloce?"
__________________
www.biffuz.it | Thou shall not follow the NULL pointer, for chaos and madness await thee at its end. Powered by: M1 @ Sonoma | 7600X @ W11 | C2Q @ XP | P!!! @ W98+BeOS | 286 @ W3.1 | C64 | iP16 | iPad8 | rPi4 | and more... |
|
|
|
|
#72 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Se si sapeva fin dall'inizio che la PS1 non funzioanva coi floating point, allora perchè creare un sistema tutto floating point notation? Se si è saputo dopo, allora inutile accanirsi a risolvere un problema di progettazione entro la data di scadenza, piuttosto spostarla.. ( ok è difficile, però almeno spiegare, a chi ha commissionato, il problema di fondo e del perchè non utilizzando la soluzione migliore andrà a vendere un prodotto che nessuno vorrà perchè penoso ). Personalmente, in qualunque cosa che faccio, o la faccio bene ( al meglio delle mie possibilità, sfruttando tutte le conoscenze che ho sulla materia ) oppure se mi rendo conto che non si può lascio stare e faccio fare ad altri il lavoro sporco
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#73 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2782
|
Il problema è che di persone che hanno le palle e/o la possibilità di dire al cliente che certe cose non si possono fare quando la realtà è che sarebbe troppo oneroso e/o stupido farle non ce ne sono molte.
Nella storia della ps1 chiaramente andava detto sin dal principio che o si riscriveva quella parte di codice come dio comanda o non si poteva procedere. Secondo me. |
|
|
|
|
#74 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Infatti il problema più grosso dei programmatori sono i manager/accounter/venditori. Risolvere problemi è una bazzecola paragonato all'effort necessario a far capire a qualcuno di loro una questione come quella di cui si sta parlando.
Ovviamente non sono tutti così. Ho conosciuto manager davanti ai quali si può stendere il tappeto rosso per le conoscenze tecniche che hanno, perché magari hanno fatto la gavetta come programmatori o hanno avuto la possibilità di acquisire know-how in materia. Comunque quella dell'hidden object è, sì, una dimostrazione di pragmatismo, ma mi fa capire che vale il vecchio detto: "tutto il mondo è paese". Di trovate grossolane e intrinsecamente scorrette ce ne sono anche in ambienti che non ti aspetteresti mai.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys Ultima modifica di cdimauro : 26-07-2013 alle 08:48. |
|
|
|
|
#75 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
||
|
|
|
|
#76 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Coniglio nel cappel... nel sorgente!
Questa, a quanto pare, ha proprio "fatto scuola" nell'ambiente.
E visti i tuoi ultimi commenti kwb, probabilmente ti prenderà un colpo ![]() --- The Programming Antihero I was fresh out of college, still wet behind the ears, and about to enter the beta phase of my first professional game project -- a late-90s PC title. It had been an exciting rollercoaster ride, as projects often are. All the content was in and the game was looking good. There was one problem though: We were way over our memory budget. Since most memory was taken up by models and textures, we worked with the artists to reduce the memory footprint of the game as much as possible. We scaled down images, decimated models, and compressed textures. Sometimes we did this with the support of the artists, and sometimes over their dead bodies. We cut megabyte after megabyte, and after a few days of frantic activity, we reached a point where we felt there was nothing else we could do. Unless we cut some major content, there was no way we could free up any more memory. Exhausted, we evaluated our current memory usage. We were still 1.5 MB over the memory limit! At this point one of the most experienced programmers in the team, one who had survived many years of development in the "good old days," decided to take matters into his own hands. He called me into his office, and we set out upon what I imagined would be another exhausting session of freeing up memory. Instead, he brought up a source file and pointed to this line: static char buffer[1024*1024*2]; "See this?" he said. And then deleted it with a single keystroke. Done! He probably saw the horror in my eyes, so he explained to me that he had put aside those two megabytes of memory early in the development cycle. He knew from experience that it was always impossible to cut content down to memory budgets, and that many projects had come close to failing because of it. So now, as a regular practice, he always put aside a nice block of memory to free up when it's really needed. He walked out of the office and announced he had reduced the memory footprint to within budget constraints -- he was toasted as the hero of the project. As horrified as I was back then about such a "barbaric" practice, I have to admit that I'm warming up to it. I haven't gotten into the frame of mind where I can put it to use yet, but I can see how sometimes, when you're up against the wall, having a bit of memory tucked away for a rainy day can really make a difference. Funny how time and experience changes everything. - Noel Llopis --- L'ho ribattezzata: "Truccone spannometrico del nonno"! ... Una chicca, posto un commento presente in calce all'articolo da cui ho estratto questa storiella, pubblicato da un certo Ken Demarest (Wing Commander): Quote:
Sempre per kwb, tra i commenti ne ho trovata una (di "storiella") che potremmo presentare così: "Bug Driven Game Design" ![]() Occhio alla genialata: Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 26-07-2013 alle 10:07. |
||
|
|
|
|
#77 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
dai arrivare a cambiare tutto per un bug....EPICO!!!
comuqnue è vero, la realtà è tristemente triste
__________________
My gaming placement |
|
|
|
|
#78 | |||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quote:
Quote:
![]() Però c'è da dire che c'è da inchinarsi all'idea geniale finale ( anche se il resto dell'approccio al problema è risultato essere non proprio ottimale ).
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|||
|
|
|
|
#79 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 3490
|
Successo a me.
da una enorme tabella piena di eventi (migliaia di linee al giorno, per anni) bisognava estrarre gli eventi accaduti nei giorni festivi in un dato anno. Paolo: "Mario, tu che ti intendi di query, puoi fare questa cosa? Io non so dove sbattere la testa. Ah, serve entro domani." Mario: "Ma è facilissimo Paolo, lo faccio subito, guarda!" Soluzione di Mario (in pseudocode giusto per rendere l'idea): Codice:
result = Query("SELECT * FROM MegaTabella WHERE YEAR(data) = " + anno + " ORDER BY data DESC").execute(); // 1M risultati, svariati minuti su un server Xeon con so quante CPU, 100 MB di risultati
while (result.hasNext()) {
riga = result.next();
data = riga.field("data");
giorno = EstraiGiorno(data);
mese = EstraiMese(mese);
if ((giorno == 1 && mese == 1) ||
(giorno == 6 && mese == 1) ||
(giorno == 25 && mese == 4) ||
(giorno == 1 && mese == 5) ||
(giorno == 15 && mese == 8) ||
(giorno == 25 && mese == 12) ||
(giorno == EstraiGiorno(CalcolaPasqua(anno) && mese == EstraiMese(CalcolaPasqua(anno))) {
FaiIlTuoBelCalcolo(riga);
}
else {
// 99% delle righe finisce qua
}
}
Risultato: la query rallentava tutto il database, a volte andava in timeout o faceva andare in timeout altre query o schiantava la VM per poca RAM. Paolo: "lo sapevo che quell'imbecille di Mario faceva casino, ma dove ha imparato a programmare, ora sistemo tutto io" Fix di Paolo: Codice:
result = Query("SELECT * FROM MegaTabella WHERE YEAR(data) = " + anno + " ORDER BY data DESC").execute(); // 500k+ risultati, svariati minuti su un server Xeon con so quante CPU, 100 MB di risultati
while (result.hasNext()) {
riga = result.next();
data = riga.field("data");
giorno = EstraiGiorno(data);
mese = EstraiMese(mese);
pasqua = CalcolaPasqua(anno);
giornoPasqua = EstraiGiorno(pasqua);
mesePasqua = EstraiMese(pasqua);
if ((giorno == 1 && mese == 1) ||
(giorno == 6 && mese == 1) ||
(giorno == 25 && mese == 4) ||
(giorno == 1 && mese == 5) ||
(giorno == 15 && mese == 8) ||
(giorno == 25 && mese == 12) ||
(giorno == giornoPasqua && mese == mesePasqua) {
FaiIlTuoBelCalcolo(riga);
}
else {
// 99% delle righe finisce qua
}
}
Alla fine la palla è passata a me. La mia soluzione: Codice:
query = Quey("SELECT <campi che ci servono> FROM MegaTabella LEFT JOIN Festivita ON MegaTabella.data = Festivita.data WHERE YEAR(MegaTabella.data) = $1 ORDER BY MegaTabella.data DESC"); // Nota: la tabella Festivita è sempre esistita
query.setParameter(1, anno);
result = query.execute(); // Pochi secondi, qualche centinaio di righe, pochi kB
while (result.hasNext()) {
FaiIlTuoBelCalcolo(result.next());
}
__________________
www.biffuz.it | Thou shall not follow the NULL pointer, for chaos and madness await thee at its end. Powered by: M1 @ Sonoma | 7600X @ W11 | C2Q @ XP | P!!! @ W98+BeOS | 286 @ W3.1 | C64 | iP16 | iPad8 | rPi4 | and more... |
|
|
|
|
#80 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
WTF? + ROLF + OMG! + LOL etc...
Potrebbe essere lo sketch di una qualche serie comica per nerd!
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:55.




















