-
Content count
5070 -
Joined
-
Last visited
Status Updates posted by Remilia Scarlet
-
I haven't worked on my Quake map in quite a while, so I figured I'd take a break from Doom for a bit.
-
Dang it, I feel torn between writing creepy dark ambient music for area one of my Doom map like I did for SoTNR, something harsh and industrial like I did for Extreme Terror, or something along the lines of Lost Years or one of John Carpenter's recent songs.
Anyone have some suggestions? Do you think synthwave-y stuff would even sound appropriate for a Doom map like mine? I'm kinda leaning towards it only because my Doom map is me experimenting with a bunch of stuff anyway, but I'm not opposed to doing other styles. Plus there'll be four separate tracks in the whole level, so it's not like I'm stuck with one style.
-
Yeah it's the same as Aeolian, so a scale goes W H W W H W W. I generally chose a minor key then work off of a natural minor scale when I write music.
The phrygian things are used in a lot of EBM/industrial and goa trance since they can sound very dark, depending on the parts of it that are emphasized. They also fit in nicely with diminished chords, but can also have the occasional minor third to fit in with minor chords and change the feel slightly.
For example, I'm pretty sure I based this song around a phrygian dominant scale (glad I uploaded this yesterday lol):
And this goa trance song, which I haven't officially released yet:
-
I think something like Excessive Exposure w/o vocals would be really awesome! Although I'd probably be dancing too much to play properly :3
-
Well I went through all my WIP songs (and whoa howdy do I always have a lot of them), and found two synthwave-y songs that would fit, and an industrial/Extreme Terror-style one that would work. I'll work on these in the next few days and see if I can't get rough mixes done just to see if they will indeed feel right in the level.
Either way, they'll be on my next album, so it's not like the work will go to waste :-P
- Show next comments 9 more
-
-
Well I finally finished* area two of my Doom map. For the ending of it, I decided to do a mini boss fight involving a cyberdemon and some spawning mobs. I wouldn't call it an IoS area by any means, but it's just vaguely similar in that mobs will occasionally spawn. Unfortunately I can't explain much more, or I'd give the fight away, and I would much rather it be a surprise.
With this, the map is about 45-50% done. I'll probably take a short (week or so) break to work on music now that it's finished.
Anyway, screenshots of the map and the boss area sans monsters:
5332 sectors so far. Yeah this is going to be my largest map to date.
*I still have some detailing and testing to finish, so it's "done" in that it's playable and looks good enough that I'm not gouging my eyes out, and I feel that I can move onto a new area.
-
I've finally released both my 2014 album "Waveforms" and my 2015 EP "H₂SO₄" on YouTube. These are also available for streaming and downloading from my website.
-
Man, after doing some serious Quake playing for a week or two, coming back to Doom is hard. I never noticed just how slippery the player movement in Doom is compared to Quake. It's like playing Sonic for 8 hours straight, then immediately attempting to play SMB3.
-
I spent most of today redoing the lighting for my (still unnamed) Quake level so that it's a bit closer to that trippy color-filled style of my Doom maps. The levels and delay/wait settings on all the lights were also tweaked quite a bit, as was the settings I'm passing to the "light" program. Overall, I'm pleased with the results ^_^
Not all of the work today was spent on lighting, though. The path to the first key is now complete, some additional detailing was done, and I learned how to do an AND logic gate using only the built-in entities.... which was then scrapped when I changed my mind about some monsters :-P All of the combat leading up to the first key is also finished and fairly well balanced. It still needs a lot more testing to be sure, though.
Newest screens:
3
-
A new unfinished room in my Quake map. I think I'm finally starting to get comfortable with 3D level editing. Still not sure what I'm going to call the level, though.
Having this reference for lighting has helped me tremendously as well.
-
I mostly did detailing and gameplay work on my Quake level today, but I did manage to make this hallway. Lights still need some adjusting, but I like where this part is going.
-
Looks very cool! If you have any more questions about quake mapping, ask around here: http://www.celephais.net/board/forum.php
I'm sure there's plenty of people who know q1 mapping that can help.
- Show next comments 9 more
-
Recorded playthroughs of SoTNR maps 2-4 and 31... only to realize that I clipped the audio when I imported the files into Cinelerra :-/
-
well... maybe I can demo a map or two. But I won't be looking around as much, I tend to just go in and fuck shit up ;-)
- Show next comments 9 more
-
-
New screenshot from my Quake level. This is a half-finished room - I still need to finish adding the monsters and some triggers, and finish adding detail. But I'm liking how it's turning out so far ^_^
-
Wait, do you mean AD_Sepulcher? I think that actually came out a few weeks ago. Quite an impressive map.
- Show next comments 9 more
-
-
Yesterday I switched from working on my Doom map back over to my Quake map, and in doing so, something came to mind: Is one project robbing ideas from the other? I'm thinking not because there are some things that are simply easier to do in Quake than in Doom, and vice versa. For example, setting up any sort of true 3D architecture in Quake is WAY easier than in Doom, and the room I worked on in Quake yesterday had a lot of 3D architecture in it. There's also nothing stating that the two levels can't share certain areas or gameplay devices - in fact, they already do because they started out as the same level.
Anyway, just a random thought I had yesterday.
-
Actually, I would like to see a pair of maps that looks almost the same in two build engines for some reason.
- Show next comments 9 more
-
Played through a Quake map called Ceremonial Circles last night and OMGWTFBBQ WAS IT AWESOME. I really liked the monster traps in it, some of which actually made me jump out of my chair. The brushwork and layout were also just superb.
https://www.quaddicted.com/reviews/czg03.html
Maybe I'll record a playthrough of it later once I re-record some of my SoTNR playthrough footage.
-
Here's my own playthrough of Shadows of The Nightmare Realm. Well, the first level of it anyway. I'll be working on the other levels in the next few days.
You can enable the subtitles if you want to see some occasional commentary.
-
I kinda think this old folk song about harvesting barley would make a wicked gothic rock or gothic metal song. If it hasn't already been done, that is.
SpoilerThere went three kings into the east,
Three kings both great and high;
And they have sworn a solemn oath,
John Barleycorn shall die.They took a plough and plough'd him down,
Put clods upon his head;
And they have sworn a solemn oath,
John Barleycorn was dead.But the cheerful spring came kindly on,
And showers began to fall;
John Barleycorn got up again,
And sore surprised them all.The sultry suns of summer came,
And he grew thick and strong,
His head well arm'd with pointed spears,
That no one should him wrong.The soher autumn enter'd mild,
And he grew wan and pale;
His bending joints and drooping head
Shew'd he began to fail.His colour sicken'd more and more,
He faded into age;
And then his enemies began
To shew their deadly rage.They took a weapon strong and sharp,
And cut him by the knee;
Then tied him fast upon a cart,
Like a rogue for forgery.They laid him down upon his back,
And cudgell'd him full sore;
They hung him up before the storm,
And turn'd him o'er and o'er.They fill'd up then a darksome pit
With water to the brim,
And heav'd in poor John Barleycorn,
To let him sink or swim.They laid him out upon the floor,
To work him further woe;
And still, as signs of life appear'd,
They toss'd him to and fro.They wasted o'er a scorching flame
The marrow of his bones;
But the miller used him worst of all,
For he crush'd him between two stones.And they have strain'd his very heart's blood,
And drank it round and round,
And still the more and more they drank,Their joy did more abound.
So, neighbours all, make sad lament.
And sorely weep and mourn,
For now you've heard the doleful end
Of bold John Barleycorn.-
@JDoyle Sounds cool, I'll check it out! The only version I've heard is a folk version.
- Show next comments 9 more
-
This is one of a few reasons I implemented that UDMF parser in my Common Lisp WAD library the other day.
> Make an irregularly shaped sector
> Apply a texture, hit align
> Fit Texture function doesn't give satisfactory results
> Command line: waddle texture-size-by-sect --sector 2993 --side front --tex-width 256 --scale 2
> Spits out 1.9176098 in less than a second
> Copy-paste into GZDB
> Textures are now seamless to the actual scale I wanted
Given that I had not one but 10 different sectors to do that with, and still have a bunch of others to do this on, having a quick tool where I just change a number or two really speeds things up since I'm no longer doing it all by hand in calc.exe.
-
@Phade102 Yes, it would, and that's exactly why I did it. Though do remember that GZDoom+UDMF can have fractional texture offsets and scales, so that's why it works. Otherwise it's as @42PercentHealthsaid.
-
Let me finish up the basic command line program (haven't committed that to bitbucket yet), then I'll let you know and provide you a binary.
- Show next comments 9 more
-
-
Ale and Ginger Chicken. Super simple, super old, but super tasty.
- 2 boneless chicken breasts
- 2 cups water
- 12oz ale (I use Alaskan Amber)
- 1/2 rounded tsp black pepper
- 1/4 tsp salt
- 2 1/2 tsp powdered ginger
- 10-20 threads saffron, OR 1/2 tsp paprika and 1/4 tsp turmeric
- 1 tbsp butter
- Corn starch, for thickening
- Heat up a pressure cooker without the lid. Add butter. Once melted, add the chicken and sear on all sides.
- Add everything else, mix well.
- Cover pressure cooker and cook for 30 minutes.
- Realize 10 minutes in you forgot the saffron. Uncover, add, then restart the pressure cooker.
- Use corn starch mixed with a bit of water to thicken
- Serve with rice.
-
Actually, after making this quite a few times, I think I'm going to adjust my recipe and put in double the pepper and salt. Otherwise it came out good as always.
-
Came to Doomworld for the Doom content; stayed for the culinary recipes.
- Show next comments 9 more
-
Had a sudden urge to hack today, so I very quickly hacked together a parser for UDMF in Common Lisp just for the hell of it. Not the cleanest code, but it works well enough. I still hope to eventually release this whole Waddle library of mine someday...
My testing so far, using my current map which has about 5.5mb of UDMF data, shows that it parses the raw text into a preliminary raw form in about 0.3-0.4 seconds on a Core2Quad @2.4GHz. A full parse from raw text to final form takes 0.7-0.8 seconds. Still needs some optimization in some places, I think, especially in the second pass.
Here's the bit of code I was using to check that it worked and get a very basic idea of performance:
(asdf:load-system :waddle) (in-package :waddle) (let* ((wad (load-wad-file #P"/mnt/storage/alexa-extended/bin/games/doom/Mine/raven/raven01.wad")) (level (get-lump wad "TEXTMAP" :as-text t :return-data t))) (time (elt (parse-udmf (parse-udmf->ast level)) 42)))
Here's the actual code, minus all the DEFSTRUCT calls to create the structs that hold stuff.
;;;; Waddle ;;;; Copyright (C) 2017 Alexa Jones-Gonzales <alexa@partition36.com> ;;;; ;;;; This program is free software: you can redistribute it and/or modify ;;;; it under the terms of the GNU General Public License as published by ;;;; the Free Software Foundation, either version 3 of the License, or ;;;; (at your option) any later version. ;;;; ;;;; This program is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;;; GNU General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Parser for UDMF data ;;;; ;;;; I've optimized this code as well as I can, but a few things are ;;;; lacking. Most glaring is that errors do not report the line or ;;;; column number during parsing. ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (in-package :p36.waddle) (eval-when (:compile-toplevel) (declaim (optimize (debug 0) (safety 1) (compilation-speed 0)))) (defparameter *udmf-line-regex* (let ((cl-ppcre:*regex-char-code-limit* 256) (cl-ppcre:*use-bmh-matchers* t)) (cl-ppcre:create-scanner "[;{}]" :single-line-mode t))) (defmacro get-valid-int (the-str) "Parses THE-STR for a valid integer and returns that integer, or nil if it could not be parsed." (let ((the-num (gensym)) (parsed-len (gensym))) `(when (not (find #\. ,the-str :test #'eql)) (multiple-value-bind (,the-num ,parsed-len) (parse-integer ,the-str :junk-allowed t) (when (= ,parsed-len (length ,the-str)) ,the-num))))) ;; ;; These constants make identifier parsing a bit faster ;; (alexandria:define-constant +ascii-num-min+ 48) (alexandria:define-constant +ascii-num-max+ 57) (alexandria:define-constant +ascii-upper-min+ 65) (alexandria:define-constant +ascii-upper-max+ 90) (alexandria:define-constant +ascii-lower-min+ 97) (alexandria:define-constant +ascii-lower-max+ 122) (alexandria:define-constant +ascii-_-code+ 95) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; UDMF Parser Class ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defstruct udmf-parser (source "" :type simple-string) (line 0 :type fixnum) (column 0 :type fixnum)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; AST Classes ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defstruct udmf-raw-block (name "" :type simple-string) (expressions (make-array 32 :element-type 'cons :adjustable t :fill-pointer 0 :initial-element '(nil)) :type (vector cons) :read-only t)) (defstruct udmf-variable (name "" :type simple-string) (value 0 :type (or simple-string fixnum float boolean))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; UDMF Parsing Condition Stuff ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define-condition udmf-parse-error (error) ((text :initarg :text :type string :reader text :initform "Could not parse UDMF data") (parser :initarg :parser :type (or udmf-parser null) :reader parser :initform nil) (data :initarg :data :type string :initform "(no data given)" :reader data))) (define-condition udmf-parse-error/invalid-identifier (udmf-parse-error) ()) (define-condition udmf-parse-error/invalid-string (udmf-parse-error) ()) (define-condition udmf-parse-error/invalid-assignment (udmf-parse-error) ()) (define-condition udmf-parse-error/invalid-block (udmf-parse-error) ()) (defmethod print-object ((obj udmf-parse-error) out) (let ((line "(unknown)") (line-num "?")) (when (parser obj) (setf line (udmf-parser-line (parser obj))) (setf line-num (udmf-parser-line (parser obj)))) (format out "Error: ~a~%Data: ~s~%Line #~a: ~s" (text obj) (data obj) (if (numberp line-num) (1+ line-num) line-num) line))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; UDMF Parsing ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; We define our own floating point parser since we don't need a lot ;; of fancy features. Just plain decimal notation. ;; ;; NOTE: Actually, UDMF allows for a bit more notation, such as ;; 12.4e20. But as the maps I've tested this on don't have that ;; notation, I haven't implemented it yet. When I find one, or ;; someone needs it, I will. ;; (defun parse-udmf-float (str &optional (error-on-int t) nil-on-error) "Parses a string into a floating point number, as defined by UDMF. Strings that have valid integers are converted into floating point numbers only if ERROR-ON-INT is non-NIL. If NIL-ON-ERROR is non-NIL, then a value of NIL is returned rather than raising an ERROR." (declare (type simple-string str) (optimize (speed 3) (safety 0) (debug 0))) (macrolet ((error-or-return (&optional (msg "Could not parse UDMF float")) `(if nil-on-error (return-from parse-udmf-float nil) (error ,msg)))) (let ((decimal-pos 0) (int-str "") (dec-str "") (int-part 0) (dec-part 0) (sign 1)) (declare (type fixnum decimal-pos sign) (type (or fixnum null) int-part dec-part) (type simple-string int-str dec-str)) ;; Check for integers (when (and (get-valid-int str) error-on-int) (error-or-return "Could not parse UDMF float: string represents a valid integer")) ;; Check for negative sign and adjust the number accordingly (when (find (elt str 0) #(#\+ #\-) :test #'eql) (cond ((eql (elt str 0) #\-) (setf sign -1) (setf str (subseq str 1))) ((eql (elt str 0) #\+) (setf str (subseq str 1))))) ;; Search for a decimal point (when (not (setf decimal-pos (position #\. str :test #'eql))) (error-or-return)) ;; Split at the decimal point (setf int-str (subseq str 0 decimal-pos)) (setf dec-str (subseq str (1+ decimal-pos))) ;; Check to make sure each part has a valid integer (setf int-part (get-valid-int int-str)) (setf dec-part (get-valid-int dec-str)) (when (or (not int-part) (not dec-part)) (error-or-return "Could not parse UDMF float, junk found in value")) ;; Return a floating point made from the parts (* sign (coerce (+ (coerce int-part 'float) (* (coerce dec-part 'float) (coerce (expt 10 (coerce (- (length dec-str)) 'float)) 'float))) 'float))))) (defun parse-udmf-identifier (token) (declare (type simple-string token) (optimize (speed 3) (safety 0) (debug 0))) (let ((char1 (char-code (elt token 0)))) (declare (type (unsigned-byte 8) char1)) (when (and (or (< char1 +ascii-upper-min+) (> char1 +ascii-upper-max+)) (or (< char1 +ascii-lower-min+) (> char1 +ascii-lower-max+)) (not (= char1 +ascii-_-code+))) (error 'udmf-parse-error/invalid-identifier :text "Invalid UDMF identifier" :data token)) ;; Check the rest of the characters (dotimes (i (1- (length token))) (setf char1 (char-code (elt token i))) (when (and (or (< char1 +ascii-num-min+) (> char1 +ascii-num-max+)) (or (< char1 +ascii-upper-min+) (> char1 +ascii-upper-max+)) (or (< char1 +ascii-lower-min+) (> char1 +ascii-lower-max+)) (not (= char1 +ascii-_-code+))) (error 'udmf-parse-error/invalid-identifier :text "Invalid UDMF identifier" :data token))) token)) (defun parse-udmf-value (token) (declare (type simple-string token) (optimize (speed 3) (safety 0) (debug 0))) (cond ((and (eql (elt token 0) #\") (eql (elt token (1- (length token))) #\")) (return-from parse-udmf-value (subseq token 1 (1- (length token))))) ((or (and (eql (elt token 0) #\") (not (eql (elt token (1- (length token))) #\"))) (and (not (eql (elt token 0) #\")) (eql (elt token (1- (length token))) #\"))) (error 'udmf-parse-error/invalid-string :text "Malformed string value" :data token))) (when (string= token "true") (return-from parse-udmf-value t)) (when (string= token "false") (return-from parse-udmf-value nil)) (or (get-valid-int token) (parse-udmf-float token))) (defun parse-udmf-assignment-expr (line) (declare (type simple-string line) (optimize (speed 3) (safety 0) (debug 0))) (when (not (eql (elt line (1- (length line))) #\;)) (error 'udmf-parse-error/invalid-assignment :text "Unexpected end of assignment" :data line)) (let ((pos-of-= (or (position #\= line :test #'eql) (error 'udmf-parse-error/invalid-assignment :text "No equal sign found in assignment" :data line))) (ident "") (value "")) (declare (type (or fixnum null) pos-of-=) (type simple-string ident value)) (setf ident (parse-udmf-identifier (string-trim '(#\Space) (subseq line 0 pos-of-=)))) (setf value (parse-udmf-value (string-trim '(#\Space #\;) (subseq line (1+ pos-of-=))))) (cons ident value))) (defun parse-udmf-block (line stream) (declare (type string-stream stream) (type simple-string line) (optimize (speed 3) (safety 0) (debug 0))) (let* ((ret (make-udmf-raw-block :name (parse-udmf-identifier (string-trim '(#\Space #\{) line))))) (declare (type simple-string line) (type udmf-raw-block ret)) ;; We now start parsing assignment expressions until we hit a } (loop do (progn (handler-case (setf line (read-line stream)) (end-of-file () (error 'udmf-parse-error/invalid-block :text "Unclosed block encountered" :data line))) (when (string= line "}") (return)) (unless (string= line "{") (vector-push-extend (parse-udmf-assignment-expr line) (udmf-raw-block-expressions ret))))) ret)) (defmacro parse-udmf-line-into-array (line arr stream) (declare (type simple-string line) (type string-stream stream) (type vector arr) (optimize (speed 3) (safety 0) (debug 0))) `(if (and (eql (elt ,line (1- (length ,line))) #\;) (position #\= ,line :test #'eql)) (vector-push-extend (parse-udmf-assignment-expr ,line) ,arr) (vector-push-extend (parse-udmf-block line ,stream) ,arr))) (defun parse-udmf->ast (udmf) (declare (type string udmf) (optimize (speed 3) (safety 0) (debug 0))) (let ((parser (make-udmf-parser :source udmf)) (ret (make-array 2 :element-type '(or udmf-raw-block cons) :adjustable t :fill-pointer 0 :initial-element '(nil))) (line "") (sub-line "") (last-end 0)) (declare (type simple-string line sub-line) (type fixnum last-end) (type udmf-parser parser) (type (vector (or udmf-raw-block cons)) ret)) (handler-case (with-input-from-string (in (udmf-parser-source parser)) (loop do (progn (setf line (read-line in)) ;; Ignore blank lines (when (not (string= line "")) (setf last-end 0) ;; We only use CL-PPCRE:DO-SCANS if we absolutely need to (if (> (count-if #'(lambda (char) (char= char #\; #\{ #\})) line) 1) (cl-ppcre:do-scans (mstart mend regs rege *udmf-line-regex* line) (setf sub-line (string-trim '(#\Space) (subseq line last-end mend))) (setf last-end mend) (when (not (string= sub-line "")) (parse-udmf-line-into-array line ret in))) (parse-udmf-line-into-array line ret in)))))) (end-of-file () ret)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; UDMF AST -> UDMF Structures Translation ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This will create a function to take a raw UDMF block and turn it ;; into a UDMF structure. ;; (defmacro create-udmf-raw-block->udmf-struct-translator (fn-name type) (declare (optimize (debug 0) (compilation-speed 0))) (let ((waddle-pkg (find-package :p36.waddle)) (fn-arg (gensym "FN-ARG-")) (ret (gensym "FN-RET-")) (expr (gensym "FN-EXPR-")) (type-accessor-prefix (concatenate 'string (subseq (string type) (1+ (position #\/ (string type) :test #'eql :from-end t))) "-"))) `(defun ,fn-name (,fn-arg) (let ((,ret (,(intern (concatenate 'string "MAKE-" (string type))) :name (udmf-raw-block-name ,fn-arg)))) (loop for ,expr cons across (udmf-raw-block-expressions ,fn-arg) do (cond ,@(loop for slot in (closer-mop:class-slots (find-class type)) when (equal waddle-pkg (symbol-package (closer-mop:slot-definition-name slot))) collecting (let* ((slot-name-str (string-downcase (string (closer-mop:slot-definition-name slot)))) (slot-accessor (intern (concatenate 'string type-accessor-prefix (string-upcase slot-name-str))))) `((string= ,slot-name-str (car ,expr)) (setf (,slot-accessor ,ret) (cdr ,expr))))))) ,ret)))) ;; ;; Create all the functions needed to turn raw UDMF blocks into UDMF structures ;;; (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-vertex udmf-block/vertex) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-linedef udmf-block/linedef) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-sidedef udmf-block/sidedef) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-sector udmf-block/sector) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-thing udmf-block/thing) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-zdoom-vertex udmf-block/zdoom/vertex) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-zdoom-linedef udmf-block/zdoom/linedef) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-zdoom-sidedef udmf-block/zdoom/sidedef) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-zdoom-sector udmf-block/zdoom/sector) (create-udmf-raw-block->udmf-struct-translator udmf-raw-block->udmf-zdoom-thing udmf-block/zdoom/thing) ;; ;; Parses the AST generated by PARSE-UDMF->AST into a vector of UDMF ;; structures and CONSes. In the resulting array, CONSes represent ;; toplevel assignments. ;; (defun parse-udmf (udmf-ast) (declare (type (vector (or cons udmf-raw-block)) udmf-ast) (optimize (speed 3) (debug 0))) (let ((ret (make-array (length udmf-ast) :adjustable t :fill-pointer 0)) (block-name "") (zdoom nil) (thing '(nil))) (declare (type simple-string block-name) (type vector ret) (type boolean zdoom) (type (or cons udmf-raw-block) thing)) (dotimes (i (length udmf-ast)) (setf thing (elt udmf-ast i)) (typecase thing (cons (format t "~a: ~a~%" (car thing) (cdr thing)) (when (and (string= (the string (car thing)) "namespace") (or (string= (string-downcase (cdr thing)) "zdoom") (string= (string-downcase (cdr thing)) "zdoomtranslated"))) ;; We're in ZDoom, so keep track of this so we can also ;; call ZDoom translation functions (setf zdoom t)) (vector-push-extend thing ret)) (udmf-raw-block (setf block-name (udmf-raw-block-name thing)) (if zdoom (cond ((string= "thing" block-name) (vector-push-extend (udmf-raw-block->udmf-thing thing) ret)) ((string= "linedef" block-name) (vector-push-extend (udmf-raw-block->udmf-linedef thing) ret)) ((string= "sidedef" block-name) (vector-push-extend (udmf-raw-block->udmf-sidedef thing) ret)) ((string= "vertex" block-name) (vector-push-extend (udmf-raw-block->udmf-vertex thing) ret)) ((string= "sector" block-name) (vector-push-extend (udmf-raw-block->udmf-sector thing) ret)) (t (format t "Don't know how to handle a ~a block~%" block-name))) (cond ((string= "thing" block-name) (vector-push-extend (udmf-raw-block->udmf-zdoom-thing thing) ret)) ((string= "linedef" block-name) (vector-push-extend (udmf-raw-block->udmf-zdoom-linedef thing) ret)) ((string= "sidedef" block-name) (vector-push-extend (udmf-raw-block->udmf-zdoom-sidedef thing) ret)) ((string= "vertex" block-name) (vector-push-extend (udmf-raw-block->udmf-zdoom-vertex thing) ret)) ((string= "sector" block-name) (vector-push-extend (udmf-raw-block->udmf-zdoom-sector thing) ret)) (t (format t "Don't know how to handle a ~a block~%" block-name))))))) ret))
-
Ahh I get it. thats really interesting. I'm not really a big fan of scripts, but I believe I do remember using a very simple one a long long time ago to place fog in a level.
As you said though, this isn't a script. it'd be interesting to see where this program can be used.
-
Wonderful work!
- Show next comments 9 more
-
-
Earlier today I finished some early versions of the music that'll be going into my Doom level. There'll be one track for each major area, plus a short "outside ambiance" sort of thing, so five total tracks.
Anyway, I put them into the pk3, wrote the ACS to fade them nicely and control them as-needed, fired up GZDoom and... holy crap it's like 300% creepier now. I'm seriously glad I usually playtest without the music.
The ambient outdoor thing isn't much, just a sound collage of some low rumbling and a recording of a creepy dog barking I found. I layered in some reverb via a convolution plugin using a canyon impulse, which makes it sound sounds pretty solid and very outdoors-y.
The outer temple area uses a song I'm calling "Drive Them Back" (named after a Vincent Price sample I use in it), which is a dark, gothic track that uses a melancholy ARP Solina for the melody. Sorta like SoTNR map 03's music, but less evil and more gloomy.
The crypt area has a track that's much more experimental and ambient. It features a droning background of noise and warmth, interspersed demonic noises, and some algorithmically generated drums that get all messed up and don't play the role of a standard rhythm track.
I'm not sure exactly what I'll be doing for the inner temple or the final area, but I noticed that Skinny Puppy's album "Cleanse Fold and Manipulate" went pretty well with the general feel so far, so I might experiment more with distorted drums and sound collage textures for them.
-
This will be interesting to listen to for sure.
Remember when you said MIDIs had their place? I feel the same way about mp3, actually. I think that, looking at these highly detailed GZDoom maps you and others make, a MIDI would feel out of place there. I can totally see why people would want for their highly detailed and styled maps to have what they feel is the absolute best fitting OST, in which case MIDIs probably just can't cut it for their inherent limitations.
At the same time, looking at the more "basic" aesthetics of non-GZDoom stuff, mp3s would be out of place there for me as well, since relatively high definition tracks would make the environment seem a lot more comical than it already is.
Anyway... Looking forward to what you're composing there. :-)
-
-
^ROFL
I will throw this MIDI into a map at some point:
Hard to resist...
- Show next comments 9 more
-
-
Now that I'm mostly past being sick, I'm back to working more consistently on my Doom and Quake maps. Having that break gave me time to step back, examine them, and decide how I want to continue to approach them moving forward.
My Doom map, ultimately, is just going to be a one-off deal. That idea of having a prequel to SoTNR is still something I'm passionate about doing, but not with this map. I just don't have access to the resources I need to realize my SoTNR prequel at this time. So it'll just be a standalone map, with no connection to SoTNR as far as story goes.
In a lot of ways, this map has become a sort of experimental playground for me, where I'm practicing with larger areas, different textures, and really pushing the lighting style I had in SoTNR map 03 further. I also really wanted to revisit the idea of having an XBAWKS HUEG map that was divided into different major areas, like in Extreme Terror. So, that's the direction I'm heading. The map starts outside, leads into a sort of outer temple, then heads into an underground dungeon/crypt. From there it will head into an inner temple, then into a torture/sacrifice area.
The Quake map is also just a one-off map that I'm using as a learning tool. It's very straight forward and doesn't experiment much. What's funny, though, is that it actually shares some rooms with my Doom map, yet changes very drastically after the first two or three rooms. This is because my Doom map started off as an experiment to see how well I could recreate my Quake map in GZDoom.
So yeah. Extreme Terror was more experimental, SoTNR was not. The new map is experimental again. It's like my Doom maps are matching how I approach writing music :-P
-
Yeah, it feels pretty positive - especially the part where I'm not coughing up a lung XD
The maps are going to be interesting, for sure. My music albums always follow the pattern (intentional or not) of More Experimental -> More Solid -> More Experimental -> More Solid... and that seems to work pretty well for them. Like the album I'm working on now is much more experimental, where I'm playing around with dark ambient and my first 2-CD release. Waveforms was more a refining of ideas I experimented with in the album that came before it. Modeling my Doom releases after this "feels right" to me.
-
Yeah, breathing is so much more fun when your lungs stay inside your body while doing so. Seems like you have a lot of projects going on yet again. Make sure not to overwork yourself.
-
Thanks, I will :) It's about the same amount, except the addition of a Quake map and the subtraction of the programming I was working on.
- Show next comments 9 more
-
-
Some minor detailing work on my first Quake level. I'm still getting used to these light settings.
-
Still getting the hang of this Quake thing.
-
BRB GETTING THE HANG OF THIS FRESH-UNDERWEAR THING. *spooge*
Nice work, as if that weren't clear. ;) -
Damn, I'd say you've got the hang of it and then some. That's awesome.
-
Looks like some place in Quake: SOA... My memory doesn't serve me well ;P
- Show next comments 9 more
-
-
Ok, I lied. I did a little bit of Quake mapping tonight.
-
What a crappy week.
So far, in the first eight days of this month, I've been in the ER twice with ear pain that was never diagnosed, I had to help my mom out when she ended up in the ER with pneumonia, I've had neck spasms caused by severe anxiety, I had my desktop's power supply die, and I had a cat get scared by a very loud firework and pee all over my couch. At least I finally found out I have an ear infection and was finally given something for it.
So yeah, no mapping for me for a while until my life unsuckifies.
-
I'm sorry so much shit is happening right now Yuki, I really do hope both you and your mother feel better. I wish there was a way I could help, but can't think of any. Best wishes.
-
:(
-
That sounds like the definition of a 'hell week' as I call 'em, basically nothing goes right once, not ever, because the powers that be say so. Wish you well!
- Show next comments 9 more
-
-
Played through this Quake map today after it was mentioned somewhere else here on Doomworld, and holy crap was it well-made. I especially loved the atmosphere, and hunt for the runes since the different areas actually felt different and were easy to differentiate. Plus the ramp up in difficulty was spot-on. Not quite my favorite (that still goes to mappi2), but it's easily my second favorite.