Doohnibor Posted May 26, 2012 Hi, I am not a programmer... just did graphics, some maps for quake, some modeling, sounddesign and a bit of scripting. I would like to take a closer look at the doom "AI", Monster behavior etc. and possibly play around a bit with it. Does anyone have a recommendation where I should begin? I do NOT intend to learn how to code an engine ; ) All I want is to understand how the gamelogic/behaviour "ticks" and try what happens if I change certain things... Any ideas where I could start at? Thanks 0 Share this post Link to post
Maes Posted May 26, 2012 I'd say starting from the Doom source code (or that of any port reasonably close to it, e.g. prBoom or Chocolate Doom) and study the p_ modules. There are no shortcuts to this process, and you will learn how to code an engine until you get there. 0 Share this post Link to post
Doohnibor Posted May 26, 2012 ok, thanks...... which of the ports - I don't care if it's outdated in terms of graphics - has the "best" documentation? found this in the doom wiki.... "The original plan for the source code release involved a book Kreimeier was to write on the Doom engine; however, due to Doom's decreasing relevance in the gaming community, it was eventually judged not to be a marketable idea, and the project was abandoned." does anyone know if something similar was ever released? 0 Share this post Link to post
andrewj Posted May 26, 2012 The AI in DOOM is a basic state machine, at any one time a monster is in a particular state (such as "spawn" state at start of map), and usually cycles to the next state after a short time, and eventually around in a loop. Each state also decides the sprite frame to use to draw the monster. When a new state is entered, the monster can perform an action, such as A_Look to look for players to attack, or A_Chase to move the monster in the general direction of the player (and maybe perform an attack too). These actions can cause state changes too, if the A_Look action sees a player then the monster go from "spawn" state to "chase" states where it uses the A_Chase action to chase and attack the player. Other events also cause a state change, shooting a monster will make it enter its "pain" states, and killing it makes it enter its "death" states. The more interesting stuff is in the code for actions like A_Chase. The p_enemy.c file in the code has most of them. 0 Share this post Link to post
fraggle Posted May 26, 2012 If you're not a programmer, I'd recommend that you *not* start by looking at the code - instead, start by experimenting with Dehacked, playing with the state tables and seeing how the monsters progress from one state to the other and different behaviors are triggered. That will provide a much more accessible way to learn how things work, and you can even experiment with changing things without the hassle of having to set up a compiler. Then, once you've learnt enough of that, and if you're curious, dig down into how the code works. 0 Share this post Link to post
Gez Posted May 26, 2012 I'd suggest you look on the ZDoom wiki. Go to the Doom actors page, look one of them up, and there you go. You'll see in the DECORATE code a streamlined, much easier to understand depiction of the original state tables; and you can click on any of the codepointers (the A_* functions like A_Chase) to see its documentation. 0 Share this post Link to post
Doohnibor Posted May 26, 2012 Thanks a lot. Those were ALL very helpful hints! ; ) 0 Share this post Link to post
printz Posted May 26, 2012 Gez said:I'd suggest you look on the ZDoom wiki. Now this was predictable of you. 0 Share this post Link to post
Gez Posted May 26, 2012 Perfectly valid nevertheless. This is the code for the cacodemon's states in Doom's source code: {SPR_SARG,0,10,{A_Look},S_SARG_STND2,0,0}, // S_SARG_STND {SPR_SARG,1,10,{A_Look},S_SARG_STND,0,0}, // S_SARG_STND2 {SPR_SARG,0,2,{A_Chase},S_SARG_RUN2,0,0}, // S_SARG_RUN1 {SPR_SARG,0,2,{A_Chase},S_SARG_RUN3,0,0}, // S_SARG_RUN2 {SPR_SARG,1,2,{A_Chase},S_SARG_RUN4,0,0}, // S_SARG_RUN3 {SPR_SARG,1,2,{A_Chase},S_SARG_RUN5,0,0}, // S_SARG_RUN4 {SPR_SARG,2,2,{A_Chase},S_SARG_RUN6,0,0}, // S_SARG_RUN5 {SPR_SARG,2,2,{A_Chase},S_SARG_RUN7,0,0}, // S_SARG_RUN6 {SPR_SARG,3,2,{A_Chase},S_SARG_RUN8,0,0}, // S_SARG_RUN7 {SPR_SARG,3,2,{A_Chase},S_SARG_RUN1,0,0}, // S_SARG_RUN8 {SPR_SARG,4,8,{A_FaceTarget},S_SARG_ATK2,0,0}, // S_SARG_ATK1 {SPR_SARG,5,8,{A_FaceTarget},S_SARG_ATK3,0,0}, // S_SARG_ATK2 {SPR_SARG,6,8,{A_SargAttack},S_SARG_RUN1,0,0}, // S_SARG_ATK3 {SPR_SARG,7,2,{NULL},S_SARG_PAIN2,0,0}, // S_SARG_PAIN {SPR_SARG,7,2,{A_Pain},S_SARG_RUN1,0,0}, // S_SARG_PAIN2 {SPR_SARG,8,8,{NULL},S_SARG_DIE2,0,0}, // S_SARG_DIE1 {SPR_SARG,9,8,{A_Scream},S_SARG_DIE3,0,0}, // S_SARG_DIE2 {SPR_SARG,10,4,{NULL},S_SARG_DIE4,0,0}, // S_SARG_DIE3 {SPR_SARG,11,4,{A_Fall},S_SARG_DIE5,0,0}, // S_SARG_DIE4 {SPR_SARG,12,4,{NULL},S_SARG_DIE6,0,0}, // S_SARG_DIE5 {SPR_SARG,13,-1,{NULL},S_NULL,0,0}, // S_SARG_DIE6 {SPR_SARG,13,5,{NULL},S_SARG_RAISE2,0,0}, // S_SARG_RAISE1 {SPR_SARG,12,5,{NULL},S_SARG_RAISE3,0,0}, // S_SARG_RAISE2 {SPR_SARG,11,5,{NULL},S_SARG_RAISE4,0,0}, // S_SARG_RAISE3 {SPR_SARG,10,5,{NULL},S_SARG_RAISE5,0,0}, // S_SARG_RAISE4 {SPR_SARG,9,5,{NULL},S_SARG_RAISE6,0,0}, // S_SARG_RAISE5 {SPR_SARG,8,5,{NULL},S_SARG_RUN1,0,0}, // S_SARG_RAISE6 { // MT_SERGEANT 3002, // doomednum S_SARG_STND, // spawnstate 150, // spawnhealth S_SARG_RUN1, // seestate sfx_sgtsit, // seesound 8, // reactiontime sfx_sgtatk, // attacksound S_SARG_PAIN, // painstate 180, // painchance sfx_dmpain, // painsound S_SARG_ATK1, // meleestate 0, // missilestate S_SARG_DIE1, // deathstate S_NULL, // xdeathstate sfx_sgtdth, // deathsound 10, // speed 30*FRACUNIT, // radius 56*FRACUNIT, // height 400, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_SARG_RAISE1 // raisestate }, It's in two different places in the info.c, and you have to refer to the lower part (the mobj declaration) to see how the states are attached. The same code on the ZDoom wiki:ACTOR Demon 3002 { Game Doom SpawnID 8 Health 150 PainChance 180 Speed 10 Radius 30 Height 56 Mass 400 Monster +FLOORCLIP +FASTER +FASTMELEE SeeSound "demon/sight" AttackSound "demon/melee" PainSound "demon/pain" DeathSound "demon/death" ActiveSound "demon/active" Obituary "$OB_DEMONHIT" // "%o was bit by a demon." States { Spawn: SARG AB 10 A_Look Loop See: SARG AABBCCDD 2 A_Chase Loop Melee: SARG EF 8 A_FaceTarget SARG G 8 A_SargAttack Goto See Pain: SARG H 2 SARG H 2 A_Pain Goto See Death: SARG I 8 SARG J 8 A_Scream SARG K 4 SARG L 4 A_NoBlocking SARG M 4 SARG N -1 Stop Raise: SARG N 5 SARG MLKJI 5 Goto See } } In addition, in ZDoom, everything is in the actor declaration. Those FASTER and FASTMELEE flags? In vanilla Doom, they don't exist, you have to grep through the source code for "MT_SERGEANT" to find out the parts that they refer to. The state table and mobj declarations are not enough, you also have to analyze common interaction functions to discover things such as why revenants prefer to punch you, or why archviles aren't retaliated against, etc. Which one is the most legible, especially for a non-programmer? 0 Share this post Link to post
Doohnibor Posted May 26, 2012 Gez said:Which one is the most legible, especially for a non-programmer? In my opinion and in this particular case... the Zdoom version. Since it's almost completely human (non-coder) readable text.... btw.. meanwhile I gathered some Dehacked info since it indeed seemed to be the simplest way to get a feeling for it.... but from what I've found so far it's too limited for the stuff that I want to look into. 0 Share this post Link to post
Coraline Posted June 6, 2012 If you are up to it, and surprised nobody has mentioned this yet, EDGE has extensive documentation on that ports' implementation (DDF) of monster/weapon states, etc. And it's n00b friendly. Something I'll get around to in the next release of 3DGE is updating that document to fit with current 1.35+ standards. However, you can see it's very easy to read as well, and doesn't take as long as DECORATE does to jump into and start editing. Same code of a Pinky that Gez posted, in Things.DDF: [DEMON:3002] SPAWNHEALTH=150; REACTION_TIME=0.23; RADIUS=30; HEIGHT=56; SPEED=10; FAST=2; MASS=400; PAINCHANCE=70%; SPECIAL=COUNT_AS_KILL,SOLID,CLIMBABLE,SHOOTABLE; CASTORDER=6; CAST_TITLE=DemonName; BLOOD=BLOOD; RESPAWN_EFFECT=RESPAWN_FLASH; ACTIVE_SOUND=DMACT; DEATH_SOUND=SGTDTH; PAIN_SOUND=DMPAIN; SIGHTING_SOUND=SGTSIT; STARTCOMBAT_SOUND=SGTATK; CLOSE_ATTACK=DEMON_CLOSECOMBAT; STATES(IDLE)=SARG:A:10:NORMAL:LOOKOUT, SARG:B:10:NORMAL:LOOKOUT; STATES(CHASE)=SARG:A:2:NORMAL:CHASE, SARG:A:2:NORMAL:CHASE, SARG:B:2:NORMAL:CHASE, SARG:B:2:NORMAL:CHASE, SARG:C:2:NORMAL:CHASE, SARG:C:2:NORMAL:CHASE, SARG:D:2:NORMAL:CHASE, SARG:D:2:NORMAL:CHASE; STATES(MELEE)=SARG:E:8:NORMAL:FACETARGET, SARG:F:8:NORMAL:FACETARGET, SARG:G:8:NORMAL:CLOSE_ATTACK, #CHASE; STATES(PAIN)=SARG:H:2:NORMAL:NOTHING, SARG:H:2:NORMAL:MAKEPAINSOUND, #CHASE; STATES(DEATH)=SARG:I:8:NORMAL:NOTHING, SARG:J:8:NORMAL:MAKEDEATHSOUND, SARG:K:4:NORMAL:NOTHING, SARG:L:4:NORMAL:MAKEDEAD, SARG:M:4:NORMAL:NOTHING, SARG:N:-1:NORMAL:NOTHING; STATES(RESPAWN)=SARG:N:5:NORMAL:NOTHING, SARG:M:5:NORMAL:NOTHING, SARG:L:5:NORMAL:NOTHING, SARG:K:5:NORMAL:NOTHING, SARG:J:5:NORMAL:NOTHING, SARG:I:5:NORMAL:NOTHING, #CHASE; STATES(GIB)=POL5:A:-1:NORMAL:PLAYSOUND(CRUSH); The Things.DDF links to others, like ATTACKS and WEAPONS. DECORATE keeps this all contained in one file (as far as I know), which I suppose the 'advantage' comes from. Still, I find this [DDF] method easier IMO because it seperates these definitions into multiple files so you have a generally better idea of what you're looking for when you start modding (things, weapons code, sound code, etc). 0 Share this post Link to post
Graf Zahl Posted June 6, 2012 Chu said:DECORATE keeps this all contained in one file (as far as I know), which I suppose the 'advantage' comes from. Still, I find this [DDF] method easier IMO because it seperates these definitions into multiple files so you have a generally better idea of what you're looking for when you start modding (things, weapons code, sound code, etc). Not correct. DECORATE supports #include and if you have a look at the ZDoom definitions you'll find quite a large number of definition files. You can put everything in one file but you don't have to. 0 Share this post Link to post
Coraline Posted June 6, 2012 Graf Zahl said:Not correct. DECORATE supports #include and if you have a look at the ZDoom definitions you'll find quite a large number of definition files. You can put everything in one file but you don't have to. Ah, I stand corrected. I haven't looked at anything Z in awhile - the WADS I've seen had all the DECORATE self-contained. 0 Share this post Link to post