Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Remilia Scarlet

Members
  • Content count

    4264
  • Joined

  • Last visited

Status Updates posted by Remilia Scarlet

  1. I finally finished the layout and core design of my first Quake map.  That I would ever get this far in making one is something I never thought I'd see.  From here I need to adjust the difficulty settings, add some additional detailing, and then playtest the hell out of it.  Then it'll be finished :^)

     

    Right now it's sitting at about 6600 brushes and 130 enemies on hard.  I have a feeling I could optimize that brush count a bit.

  2. 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.

     

    7JAxECL.png

    1. Nevander

      Nevander

      That looks awesome. Love the lighting.

  3. 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.

    1. Show previous comments  6 more
    2. Remilia Scarlet

      Remilia Scarlet

      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:

      https://www.partition36.com/random-stuff/in-a-dream.mp3

    3. Major Arlene

      Major Arlene

      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

    4. Remilia Scarlet

      Remilia Scarlet

      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

    5. Show next comments  3 more
  4. 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:

     

    PprCkjl.png

     

    VI1uOp9.png

     

    BB18aIu.png

     

    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.

  5. 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.

     

     

     

    1. leodoom85

      leodoom85

      I just listened to one of your tracks in YT....liked it

    2. Khorus

      Khorus

      Haven't heard any of your music lately, I'll be listening while mapping later on. Still have my "Inside the Beat" CD. :)

    3. Nine Inch Heels

      Nine Inch Heels

      Sounds good (pun 100% intended) ;-)

  6. 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.

  7. 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:

     

    szX84aw.png3

     

    1pdPBAm.png

     

    w98xIJh.png

     

    tU1g9q6.png

     

    BJ2pI2X.png

     

    SF1fNQ7.png

     

    hLglOhr.png

    1. everennui

      everennui

      So I just downloaded it... wow. I'm already lost. haha

    2. Remilia Scarlet

      Remilia Scarlet

      Uhh, probably windows vista or higher and anything more powerful than a leafblower should run it.  I ran it successfully on a core i3 with a graphics chip that couldn't do more than OpenGL v1.1, so it has very modest requirements.

    3. Remilia Scarlet

      Remilia Scarlet

      Hit me up if you need help getting started :-P

    4. Show next comments  3 more
  8. 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.

     

    SR59pPf.png

     

    Having this reference for lighting has helped me tremendously as well.

    1. Lila Feuer

      Lila Feuer

      I love it, it looks fucking evil.

    2. leodoom85

      leodoom85

      Quote

      Still not sure what I'm going to call the level, though.

      idk...call it Inner Fear or something similar ;)

  9. 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.

     

    NZFlkXh.png

    1. Remilia Scarlet

      Remilia Scarlet

      Yeah, except this was taken in Quakespasm.

    2. Breezeep

      Breezeep

      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.

    3. Remilia Scarlet

      Remilia Scarlet

      Thanks!  I'll keep that in mind.

    4. Show next comments  3 more
  10. Recorded playthroughs of SoTNR maps 2-4 and 31... only to realize that I clipped the audio when I imported the files into Cinelerra :-/

    1. Show previous comments  6 more
    2. Remilia Scarlet

      Remilia Scarlet

      I'll check it out next time.  I can't complete any of the SoTNR maps on UV without dying, so having quicksave and quickload is a necessity.

    3. Nine Inch Heels

      Nine Inch Heels

      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 ;-)

    4. Remilia Scarlet

      Remilia Scarlet

      I appreciate the thought, but these are meant to be slow playthroughs with my own commentary layered on top of them via YouTube subtitles.  I'm slowing down in very specific points to mention things.

    5. Show next comments  3 more
  11. Fellow Skinny Puppy fans might enjoy this...

     

    https://www.youtube.com/watch?v=gKY0nwUrTXA

    1. Khorus

      Khorus

      Bloody hell yes! Al Jourgensen too.

  12. 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 ^_^

     

    9rKjdjt.png

    1. Remilia Scarlet

      Remilia Scarlet

      Wait, do you mean AD_Sepulcher?  I think that actually came out a few weeks ago.  Quite an impressive map.

    2. R1ck

      R1ck

      yeah. that one, by the looks of it, it's way better looking than the original E1M3.

    3. Remilia Scarlet

      Remilia Scarlet

      It's definitely a visual masterpiece, but I wasn't too happy with how it played.

    4. Show next comments  3 more
  13. 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.

    1. Show previous comments  1 more
    2. Remilia Scarlet

      Remilia Scarlet

      Well, I also get tired of doing a bunch of Doom mapping, so switching to Quake is a nice break.  Thus it effectively means being more productive overall: my time not spent mapping for one is spent mapping for the other (or you know.... it's spent playing WoW)

    3. GarrettChan

      GarrettChan

      Actually, I would like to see a pair of maps that looks almost the same in two build engines for some reason.

    4. Remilia Scarlet

      Remilia Scarlet

      *makes a mental note for her next project*  That actually does sound sorta cool.

    5. Show next comments  3 more
  14. 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.

    1. Albertoni

      Albertoni

      Well, I know what I'll play tomorrow then!

    2. Urthar

      Urthar

      Downloading...

  15. 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.

     

     

    1. rdwpa

      rdwpa

      Cool, this will answer a lot of questions. :) 

    2. Tracer

      Tracer

      This looks amazing.

    3. GarrettChan

      GarrettChan

      Nice, I like how you admire your own work occasionally ;P   I would like to read/listen to more commentary.

  16. 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.

     

    Spoiler

    There 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.

     

    498ed76be651cffb6bb9bac6a9bb75c3.png

    1. Tracer

      Tracer

      I never understood what made "gothic" metal sound "gothic."

       

      Can you explain this to me in short?

    2. Tracer

      Tracer

      Specifically what aspects of gothic music set it apart from other forms of music.

    3. Remilia Scarlet

      Remilia Scarlet

      @JDoyle Sounds cool, I'll check it out!  The only version I've heard is a folk version.

    4. Show next comments  3 more
  17. 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

    > Seam appears horizontally no matter what because of the texture size/total linedef length discrepancy

    > 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.

    1. Remilia Scarlet

      Remilia Scarlet

      @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.

    2. Phade102

      Phade102

      I am currently building in gzdoom udmf format, so it should be fine O.o

    3. Remilia Scarlet

      Remilia Scarlet

      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.

    4. Show next comments  3 more
  18. 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
    1. Heat up a pressure cooker without the lid.  Add butter.  Once melted, add the chicken and sear on all sides.
    2. Add everything else, mix well.
    3. Cover pressure cooker and cook for 30 minutes.
    4. Realize 10 minutes in you forgot the saffron.  Uncover, add, then restart the pressure cooker.
    5. Use corn starch mixed with a bit of water to thicken
    6. Serve with rice.
    1. Remilia Scarlet

      Remilia Scarlet

      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.

    2. Zakken

      Zakken

      Came to Doomworld for the Doom content; stayed for the culinary recipes.

    3. Fonze

      Fonze

      Yes 

      Pics please; my eyes hunger for the foodpr0ns ;p

    4. Show next comments  3 more
  19. 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))
    

     

    1. Phade102

      Phade102

      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.

    2. Rosh Fragger

      Rosh Fragger

      I mostly play Watch Dogs 2 in such urges lol

    3. Csonicgo

      Csonicgo

      Wonderful work!

       

    4. Show next comments  3 more
  20. 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.

    1. Nine Inch Heels

      Nine Inch Heels

      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. :-)

    2. Remilia Scarlet

      Remilia Scarlet

      Hmm... comical...

       

      *plans to use Yakety Sax in a vanilla map*

    3. Nine Inch Heels

      Nine Inch Heels

      ^ROFL

       

      I will throw this MIDI into a map at some point:

       

      Gradius III cosmo-plant.zip

       

      Hard to resist...

    4. Show next comments  3 more
  21. 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

    1. Remilia Scarlet

      Remilia Scarlet

      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.

    2. Nine Inch Heels

      Nine Inch Heels

      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.

    3. Remilia Scarlet

      Remilia Scarlet

      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.

    4. Show next comments  3 more
  22. Some minor detailing work on my first Quake level.  I'm still getting used to these light settings.

     

    09c3UTy.png

    1. Megalyth

      Megalyth

      "Minor" you say. This looks fantastic.

    2. Fonze

      Fonze

      Lookin' good Yuki!

  23. Still getting the hang of this Quake thing.

     

    JeyiYZZ.png

    1. Jayextee

      Jayextee

      BRB GETTING THE HANG OF THIS FRESH-UNDERWEAR THING. *spooge*

      Nice work, as if that weren't clear. ;)

    2. Megalyth

      Megalyth

      Damn, I'd say you've got the hang of it and then some. That's awesome.

    3. GarrettChan

      GarrettChan

      Looks like some place in Quake: SOA... My memory doesn't serve me well ;P

    4. Show next comments  3 more
  24. Ok, I lied.  I did a little bit of Quake mapping tonight.

     

    XN6G4pr.png

    1. R1ck
    2. Lila Feuer

      Lila Feuer

      Looks cool AF, idk if its just me or something but I almost always think Quake looks amazing even with just normal detail architecture. It must be the lighting.

    3. Remilia Scarlet

      Remilia Scarlet

      I think it is. Lighting plays a huge role, even IRL.

  25. 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.

    1. Show previous comments  2 more
    2. MrGlide

      MrGlide

      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.

    3. R1ck
    4. Lila Feuer

      Lila Feuer

      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!

    5. Show next comments  3 more
×