File: reference.adoc

package info (click to toggle)
wadc 3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 7,352 kB
  • sloc: java: 3,808; ansic: 1,950; xml: 135; makefile: 67; sh: 34
file content (1045 lines) | stat: -rw-r--r-- 37,476 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
= WadC ("Wad Compiler")
Jonathan Dowland <jon@dow.land>; Wouter van Oortmerssen
:toc:
:toc-placement: preamble
:toclevels: 5
:homepage: https://jmtd.net/wadc/

toc::[]

== What is it?

A programming language for the construction of Doom maps. Integrated 
environment, shows you what the map described by the program looks like at the 
press of a key, and gives visual feedback about errors. Saves .wad files that 
only need to be BSP'ed. The programming language is a cross between a macro 
preprocessor and a lazy functional programming language. Unless you enjoy
both programming & Doom editing, you are unlikely to be interested in this
software.

== Who wrote it?

Since 2008, WadC is developed by Jonathan Dowland <jon@dow.land>.

WadC was originally written by Wouter van Oortmerssen
(link:http://strlen.com/wadc/[Aardappel]) in 1999.

== Version history

See link:release_notes.adoc[Release notes and version history].

== Requirements

- any computer that runs Java 1.8 or better
- any version of Doom
- a Doom nodebuilder (link:zdbsp[https://github.com/rheit/zdbsp] recommended)


== Source code

This distribution comes with full source, which is released under the
GPL (GNU Public License, version 2. see the included LICENSE.txt file.)


== Installation


You need a Java runtime environment installed to use WadC. Get one from
https://adoptopenjdk.net/ if you don't have it already.

Unpack the whole zip to any directory you like. On most systems, just
double-click or activate the "wadc-3.1-jar-with-dependencies.jar" file. From a
command line in the location where you extracted the ZIP, could also run

    java -jar wadc-3.1-jar-with-dependencies.jar

To play the .wad files you create using WadC in Doom, you also need a
node builder, such as zdBSP, available from https://github.com/rheit/zdbsp
For a list of other node builders, see http://doomwiki.org/wiki/Category:Node_builders

=== Sneak-peek: command-line interface

There is a very early-stages command-line interface now available. To
launch it, you need to run

    java -cp wadc-3.1-jar-with-dependencies.jar org.redmars.wadc.WadCCLI path/to/input.wl

It will attempt to parse, run and write out to path/to/output.wad. Be
aware that this is alpha quality, consider this a tech preview :)

== What else is in the zip?


The zip also includes

examples/:: example WadC files to try out.
include/::  a copy of the WadC "standard library". This is also
            embedded in the JAR, but is included so you can read
            it and see how it works. See also "Include files",
            below.
extra/::    Syntax definition files for editors. Currently only
            Vim, and that is in an early stage. Patches welcome!

== Using the GUI

Assuming you got it to run, you will now see the main screen, divided in an
editor part (here you write the program), a 2d map view, and an output
pane (error messages and the like appear here).

The file menu takes care of loading & saving your programs, this should all
be pretty obvious. The default extension for a program is .wl ("Wad Language").

In the program menu, "Run" runs your current program. You should do this 
frequently to see what your map looks like. If there were errors parsing your 
program the error will be shown in the output pane, and the cursor position in 
the source code after the point the error was discovered. If it parsed ok, your 
program will run which will generate a map. Runtime errors will be reported to 
the output pane, and some runtime errors that relate to particular lines or 
sectors will highlight the line or sector causing the error in red. In general 
these colours are use in the 2d view:

- white: one sided linedef
- grey: two sided linedef
- green: vertices & unassigned linedef (assigned to sector 0 upon saving a wad)
- red: line/sector that caused a runtime error
- purple: last line (and vertex) the program generated
- blue: things, and lines with special types
- yellow: newly drawn lines (press "Run" to make them green)
- dark grey: grid lines at 64 distance

You can zoom by left-clicking, and zoom out by right-clicking (in both cases,
where you click is made the new center of the map). Additionally you can pan
around by dragging the mouse, larger drags cause larger movements (you drag
whatever you grab to the position you release it on).

Instead of typing commands to draw lines, you can hold down control and click 
with the mouse (grid snap = 16 only, sorry), which will draw a line (or a curve 
if you hold down alt instead, or just step to a new position using shift) 
between the last vertex and where you clicked, and insert the code to draw this 
line at the end of the main function (so that, if you press "Run", it will 
regenerate itself correctly!). This needs atleast one starting line, and 
"standard.h" included. This is a very useful feature for drawing complex shapes, 
and for producing "glue code" between functions. After WadC has generated the 
code, you can copy it to another function etc. If you made a mistake in drawing 
you can simply delete the code from the edit window and try again (keep pressing
"Run" in between).

"Run / Save / Save Wad" runs the program as above, and if succesful writes the
sourcefile, and a .wad to the same directory and with the same name as the .wl
file. Before loading it up in Doom you have to run it through a nodebuilder.

"Run / Save / Save Wad / BSP/ DOOM" as above, but now also runs the nodebuilder
on it, and then your favourite doom port. You can set which bsp / doom port you
want to use and where they are located by modifying "wadc.cfg", (see "configuration
file").


== The Language

For most people it will be easiest to think of the language as a powerful
macro language. It consists of a set of builtin functions that allow you
to draw lines and sectors and such, and a way to abstract over them using
a function.


=== Lexical stuff

The language just knows two literals, integers (23, 0, -1 etc.) and strings
("LITE5"), the latter sofar mainly used for texture names.

Identifiers are made up of lower or upper case characters, and are allowed to 
contain digits or "_".

The source is in free format (i.e. it doesn't matter how you layout your
code). Single line comments start with "--" and last for the rest of that line,
multiline comments is anything enclosed in /* */ (not nested).

=== Printing, quitting

    print("foo")

Prints the argument to the output pane (or standard output in command-line mode).

    die("argh")

Stop evaluating the program and report the argument to the output pane. Useful for
fatal errors.

=== Integer expressions

The following builtin functions allow you to do simple operations on integers:

    add(x,y)
    sub(x,y)
    mul(x,y)
    div(x,y)

same as x+y x-y etc.

    eq(x,y)
    lessthaneq(x,y)

same as x==y and x<=y, returning 1 if true or 0 if false. To do other comparisons
simply rearrange your code :)

    sin(x)
    asin(x)

sin takes an argument in degrees (not radians) *10, i.e. 90 degrees is 900. It
returns the 1.0 to -1.0 range as 1024 to -1024. asin performs the inverse
transformation over the same ranges.

=== Bitwise expressions

Three bitwise operators are provided. These are mostly useful for setting flags:

    and(a,b)
    or(c,d)
    not(e)

equivalent to A · B, C + D, ¬E.

=== String expressions

    cat(a,b)

Just one: `cat` concatenates two expressions into one string.

=== If Then Else

is an expression of the form "exp ? exp : exp" as in C/Java. For example

    lessthaneq(a,0) ? 0 : a

returns a, unless it is negative then it returns 0.


=== Concatenating expressions

Writing any two expressions seperated by a space simply creates a new 
expression, where the expressions get evaluated in order, but the result is the 
value of the second expression. This is equivalent to the "," operator in C/Java 
and makes sense if you want to evaluate a number of expressions which are 
actually statements (expressions that are used for their side effect, not for 
their result). For example:

    print("a = ") print(a) a

is one expression that first prints two things to the output pane, and returns 
"a" as the result of the whole. This can be used anywhere, for example in an if 
expression:

    lessthaneq(a,0) ? print(a) 0 : a

if for example you wanted to debug what "a" was when it is negative.


=== Bracketing expressions

You can freely use "{" and "}" to bracket (groups of) expressions to make
more complex cases of if's clear in meaning. for example:

    a ? b : c d

both c and d are part of the else part of the if. To prevent this, write:

    { a ? b : c } d


=== Function/Macro definition

This is where the fun starts. WadC's functions are like macros because they don't
evaluate their arguments but just pass them on. But unlike macros they can do
things normally only functions can do like recursive calls.

To define a function that takes no arguments, simply write:

    name { exp }

This would allow you to use "name" everywhere and it would result in "exp" being 
evaluated. To add parameters, simply add them as a comma seperated list between 
parentheses, i.e.:

    name(a,b,c,...) { exp }

The parameter names you mention between the parentheses can now be used in
the "exp" part, and to use this function you have to specify values as
arguments. What is cool is that there are no restrictions to what you can
pass as arguments, it can even be any bit of code! As an example:

    twice(x) { x x }

    twice(print("heh"))

will print "heh" twice. In most languages you would pass the result of print(),
here you pass the actual code. This leads to new coding habits, for example in
designing a map you often need to do something different in a certain case of
your function. So instead of writing:

    dosomething(x) {
      blah(x)
      eq(x,0) ? print("something special has to happen here") : 0
    }

    dosomething(2)
    dosomething(1)
    dosomething(0)

You could write:

    dosomething(x,y) { blah(x) y }

    dosomething(2,0)
    dosomething(1,0)
    dosomething(0,print("something special has to happen here"))

You can disable this "lazy" way of argument evaluation by giving the
variable a name that starts with an "_", i.e.:

    twice(_x) { _x _x }

    twice(print("heh"))

will print "heh" just once. There are really very few cases where this
is needed (mostly in recursive functions).


=== Include files

You can include another WadC sourcecode file using "#", for example:

    #"standard.h"

this will include the file "standard.h" in your
program (actually, it will append it to the end of it, so if it has any
errors WadC will report linenumbers beyond the end of your file :)

WadC will first look in the directory containing your current .wl file
to find the file you asked for. If it isn't there, WadC will then try
to load it from within the embedded copy of the standard library.

Generally, ".h" is used for files that are only useful when included
somewhere (i.e. don't contain a "main" function) and ".wl" for normal
sources. "standard.h" contains useful macros, it should be included
in any program really.

WadC's set of standard include files contain a wide range of useful
language, doom & architectural macros that are very useful and speed
up editing a lot. You should make sure to get familiar with them.
See <<standard-library,Standard Library>> for descriptions of them
all.

=== The choice operator

The choice operator can be placed between one or more expressions,
and will make WadC choose one at random:

	print({ "hi!" | "hello!" | "how do you do!" })
	
will print one of the three strings at random, giving each 1/3rd a
chance of being picked. What is the use of this? Maps with (controlled)
random features maybe? you figure it out. Look at the "hexagon" sources
for an extensive example.

As a convention it is a good idea to bracket choice expressions with {}
as shown in the example above... but it is not needed. Choice expressions
may appear anywhere where the constituent expressions are valid.

Caveat: WadC makes its choice which expression to pick _when the function
they appear in is called_, not when they are supposed to be evaluated:

    blah {
      for(1,4,straight({ 64 | 32 }))
    }

will draw all 4 lines at length 64, or all at 32, but not a mixture.
This feature is there to make it easier to have a random choice be
repeated, which would otherwise be impossible. To force a random choice
at every iteration, use a function:

    len { 64 | 32 }

    blah {
      for(1,4,straight(len))
    }

If you want to use choice in a level but want reproducibility, you can seed
the random number generator:

    seed(1337)

This affects any use of the choice operator that follows.

=== random numbers

    rand(x,y)

Returns a random integer within the range x to y, inclusive. `rand` uses the
same Random pool as the choice operator, and is similarly affected by the use
of `seed`.

=== Simplex noise

   simplex(x,y)

The `simplex` function returns a number between 0 and 1,000,000 based on the
supplied X/Y coordinates into a 2D Simplex "field". This is useful for generating
landscapes or any other structure of feature which requires smoothed noise. To
get smooth changes, use small iterations over X and Y, for rougher transitions,
use larger.

`simplex` is entirely deterministic, reproducible and not affected by `seed`.

=== Tuneable Knobs

When developing maps in WadC, it is sometimes useful to structure a set of
variables as switches for map behaviour. Examples might be turning on "high
detail mode", or setting a global default light level, or ceiling height,
or the number of things in a population, or the size or scale of geometry.
E.g.:

    lightlevel { 200 } -- default light level
    ...
    main {
    ...
        leftsector(0, 400, lightlevel)
    ...

It is possible to mark such variables as tuneable Knobs. WadC provides a UI
of sliders for such variables that can be adjusted to quickly experiment with
different combinations of values. To mark a variable as a Knob, use
`knob(label, min, value, max)`. E.g.

    lightlevel { knob("lightlevel", 0, 200, 255) }

The first time a `knob` expression is evaluated, it returns the value
declared within, and registers a Knob with the given label, value, and
minimum/maximum bounds.

The WadC UI provides visual sliders to set a different value for the Knob
within the minimum/maximum bounds.

Subsequent evaluations of `knob` with the same label will return the value
set in the UI. If the subsequent `knob` declarations specify different
minimum/maximum bounds, the value will be clamped within that range and
the registered bounds updated.

Setting the value of Knobs is not currently possible from the CLI.

Several of the examples provided with WadC define knobs. Try loading one
into the GUI, tweaking the sliders and Running the results.

=== Doom Specific Commands

The bit you have been waiting for :)

First let me explain how evaluation and map construction works. At any
stage you always have a current vertex (and also a current line). Besides
that, you have an orientation, which is the direction you will draw in
if you draw a line. Unlike languages like Logo, you can't just look in
any direction, but just in 4: north, east, south, west. The thinking
behind this is that if you could move in an arbitrary angle, it would
be hard to keep track of your imaginary grid, and also that most maps
will have parts that can benefit from rotating to any of these 4 directions,
but more than that is hardly useful. Note that having these 4 directions
doesn't mean you can't draw lines in arbitrary directions, it only affects
which way you are looking.

    rotright
    rotleft

rotate you 90 degrees, e.g. "north rotright" is equivalent
to "east".

    getorient

Tells you the current orientation as an integer: 0 for North, 1 for East,
2 for South, 3 for West.

    up
    down

control whether the "pen" is up or down. If it is down (default)
moving about will create linedefs (hint, use macros from standard.h
instead of these).

    step(forwards_backwards,sideways)

This is the main drawing command. It draws a line from the current
vertex to a new position which will become the new current vertex.
The first value determines how many units to go forwards in the
direction you are looking, if it is negative you will go backwards.
The second parameter determines a sidestep from this, 0 means
straight ahead, positive numbers step towards the right, and negative
ones to the left. For example, if you were looking north, and wanted
to draw a line that goes 45 degrees across a 64 unit square towards
the north-east, you would write:

    step(64,64)

Here you see why that 4 direction system is useful: if you were using
arbitrary angles you would have needed to write something like 
"rotate(45) step(mul(sqrt(2),64))" which would be horribly clumsy and
imprecise, assuming it would use floats.

To make creating linedefs easier, some shorter macros exists (defined
in "standard.h" to make life easier.

    curve(forward,sideways,subdivisions,xoffdir)

draws a 90 degree curve out of linesegments, the number of which is determined by
subdivisions. After the curve, the current orientation is rotated accordingly.
Curve automatically uses and increases the current xoff value to get perfect texturing,
and thus also allows multiple curves to be fitted together perfectly. Remember to
call xoff(0) after a series of curves to reset its value when needed.
xoffdir can be 1 or -1, and determines wether xoff values should be increasing
or decreasing.

    leftsector(floor,ceil,lightlevel)
    rightsector(floor,ceil,lightlevel)

create a new sector, with given floor/ceiling levels and light level.
the sector will be created from the last linedef drawn before this
command, and either to the left or the right of it (left means the
sector to the left, looking from the one before last vertex towards
the last vertex. Because making sectors always needs to be done after
the last line, it requires a bit of planning in your code (i.e. it
is a lot of hassle to make a sector out of something your are not
currently drawing, though it can be done (by overwriting any line of
it)). These commands can cause runtime errors if you ask to create
a sector out of something which is not closed off, or has some sidedef
already assigned to another sector etc. See also pitfalls below.

    innerleftsector(floor,ceil,lightlevel)
    innerrightsector(floor,ceil,lightlevel)
    popsector

same as the two commands above, but now as extra also assign the other
sidedef to the last sector created before this one, i.e. this new
sector is created inside the last sector.
popsector makes the sector before the last sector the one used for
attaching an innersector to, i.e. you can use this directly after
an innersector command if you want to place another innersector next
to the current one (rather than inside it).

    thing

Creates a thing of the current thingtype, with the current vertex
as position (default is playerstart) and the current orientation as
the things facing angle. You can change the type of
thing being added by using

	setthing(type)

where type you have to take from uds.txt, or better still use
monsters.h / pickups.h / decoration.h / spawns.h include files instead.

If you need to fine-tune the angle that things are facing, use

    thingangle(angle)
    angle_east
    angle_ne
    angle_north
    angle_nw
    angle_west
    angle_sw
    angle_south
    angle_se

`thingangle` takes a value in degrees, with 0 degrees facing West.
The constants `angle_east`, etc are defined in `standard.h` for your
convenience.

To fetch or adjust the flags used for creating new things, use

    setthingflags(flags)
    getthingflags

Useful in conjunction with the bitwise operators. See the `thingtypes.h`
library for useful definitions.

    setthingargs(tid,zpos,special,arg1,arg2,arg3,arg4,arg5)

Sets thing argument parameters for hexen-format maps. Using this command
automatically changes the output wad to hexen format.

    linetype(type,tag)

Sets the current type & tag for lines being drawn. Needs to be reset to 0
manually. (see below for how to use tags).

    sectortype(type,tag)

sets current type & tag for the next sectors being creates. Needs to be reset
to 0 manually. (see below for how to use tags).

    linetypehexen(type,arg1,arg2,arg3,arg4,arg5)

same as linetype above, only now for hexen/zdoom style wads. Using this command
automatically changes the output wad to hexen format.  Note that arg1
in linetypehexen() is the same as tag in linetype().
Check out zdoom.h for some useful macros.

    setlineflags(flags)
    getlineflags

Similar to the thing equivalents: fine control over linedef flag values.
Useful in conjunction with the bitwise operators. There are some linedef
flag constants defined in `include/lines.h`.

    getfloor
    getceil
    gettop
    getmid
    getbot

Return the current flat/texture in use.

    floor(flat)
    ceil(flat)
    top(texture)
    mid(texture)
    bot(texture)

Sets the current texture for any of these items. The first two require a name of 
a flat, the last 3 of a texture (not a patch). Names can be easily looked 
up/browsed in a Doom resource editor/browser such as http://slade.mancubus.net[SLADE].

Currently WadC doesn't check this is a valid texturename, it just uses it. 
The good side of this is that you can use custom texture wads by just using the 
correct names and adding the wad to -file. Who knows in the future WadC may 
support a texture browser and automatic saving of custom textures, but it is not 
a priority. bot/top/mid get assigned to both sidedefs upon creation of the 
linedef (using step), floor/ceil are assigned when leftsector/rightsector is 
executed.

By default, WadC automatically removes mid-textures on doublesided linedefs.
You can toggle this on and off using the 'midtex' command:

    midtex

Tip: wrap all your texture uses in a function:

    lite5 { mid("LITE5") }

not only is it easier to write but it will make it extremely easy to experiment 
with alternative texture choices in a map.

    xoff(offset)
    yoff(offset)

set the current texture offsets (used on lines drawn). don't forget to set them
back to 0 when done.

    unpegged

sets both lower & upper unpegged. calling it again resets to normal.

    impassable

By default, two-sided lines are passable. Setting 'impassable' prevents this.

    arch(height,width,depth,subdivision,floor,lightlevel)

(experimental) makes an arch, of a certain base height, starting at a certain floor
level. width is across the arch, depth is into the arch, subdivision should divide
width, i.e. if width = 128, then subdivision = 64 gives you sectors of 2 units wide.
Arch adds to xoff automatically to reduce funny texturing. On the y axis it is best
if you precede arch by unpegged.


    archclip(height,width,depth,subdivision,floor,lightlevel,clip)

This is a special-case version of arch which has an additional parameter, clip, to
cut short generating the arch. This can be used to create structures such as gothic
arches.

    mergesectors

turns sector merge mode on. In this mode WadC will check for existing sectors
with identical properties when creating a new sector, and if one exists,
assign the sidedefs of the new sector to the existing sector instead. This
will enable you to create maps with very few sectors :)
Only use this option when necessary, as GL doom ports seem to have a hard time
triangulating sectors like this.

    prunelines

when this is on, removes all linedefs (when saving) that have the same
sector on both sides, and linedefs with no sidedefs at all. This is often
used in combination with mergesectors, and avoids the "sidedefs assigned
to same sector" error.

    lastsector
    forcesector(index)

returns the index (not tag!) of the last sector created. you can use this
value with together with forcesector, to add sides to a sector which is not
spacially adjoining it. forcesector will force the next makesector command
to add sidedefs to the sector specified instead of creating a new one. The
properties specified in the makesector command (floor level etc) are ignored.

Clearly there are a few Doom specific types and flags missing, this will
come in future versions.

==== Line splitting/merging

If either a line or a vertex is drawn on exactly the same location as an
existing line or vertex then the drawing command is ignored, i.e. if a
line is drawn multiple times, the properties of the first (textures etc.)
are remembered. This is useful for combining macros that draw complex
shapes.

But WadC supports a more advanced system for combining complex sectors:
for all horizontal and vertical lines it will automatically perform all
splitting of existing lines necessary, and insertion of vertices etc.
This means you can write macros that generate complex sectors, and
combine them with others, without having to worry how they match up.


==== "world coordinates" xoff alignment

If you make maps with lots of detail, and thus many short lines,
setting xoff correctly for each of them becomes unmanageable. For
those kind of maps, you can use "world coordinates" to assign good
xoff values automatically.

    undefx

this command "undefines" the current xoff. undefined xoff coordinates
get set automatically by WadC according to the coordinates of the vertices
on both end points. so for example if you have 4 linedefs of length 16,
between vertices (0,0) (0,16) (0,32) etc, then the xoff will be
automatically set to 0, 16, 32 etc (or their negative equivalents,
depending on which direction the line is going). because (sadly)
doom doesn't support texture scale, this can only work for linedefs that
are parallel to either the x of y axis.

If you make your map with "undefx" in mind, i.e. by aligning architecture
to power of 2 grid coordinates, you can align a whole map automatically.
You can still use the xoff() command command for specific lines that you
want to align in specific ways, just make sure to undefx afterwards.

the curve() command is not affected by undefx, it uses its own alignment.



==== Position / Texture memory

This is a language feature specifically meant to make drawing complex
forms easier. Often you will draw a lot of lines and sectors and
change textures, and want to get back to a certain point to continue
drawing there. These two expression do just that:

    !name

Store the current position (vertex), orientation, and textures in the (global) 
variable "name".

    ^name

Go back to the position/orientation stored in "name" and restore the textures.


==== Using Tags and Tag Identifiers

These are especially useful in combination with the linetype & sectortype
commands. Simply use any identifier prefixed by a "$":

    linetype(88,$exitlift)
    sectortype(0,$exitlift)

whereever the same tag is used, a unique tag number is automatically generated and
used.

If you want to generate a new, unique tag without using a tag identifier, you can
use 'newtag'

    set("myvar", newtag) -- gets a new, unused tag number
    -- ...
	linetype(sometime , get("myvar")) -- use it
    -- ...

===== Caveats

`newtag` and tag identifiers pull unique tag numbers from the same "pool" so you
can mix and match them. However, if you use bare numbers as tag arguments and use
`newtag` or tag identifiers, you run the risk of clashing the generated numbers
with your hand-chosen ones.


==== Auto texturing

This is a very powerful feature which lets you create "rules" that say
how a map should be textured, instead of doing it by hand.

Only surfaces that have the "?" texture assigned to them, will be auto textured.
This has the advantage that you can still perform manual texturing in those cases
where you can't write a rule to express what you want. You can easily use
autotexall() to set all texture to "?".

You specify rules using the following command:

    autotex(type,size1,size2,size3,texture)

This reads: apply "texture" to any surfaces that are of type "type",
and comply with size constraints "size1", "size2" and "size3".

Note well, if you specify multiple rules, then the *LAST* one that is
applicable for a certain surface will be used. So you should start your
list of rules with the general ones, and work towards the specific cases.

if you write a set of rules where none are applicable to a certain
surface, the surface will be given some default texture, so make sure
your rules cover all cases.

type must be one of:

	"C" for ceiling
	"F" for floor
	"U" for top/upper
	"N" for middle/normal
	"L" for bottom/lower
	"W" for any of upper/normal/lower

Texture is a texture name as used in the texture commands above.

The size parameters for any wall surfaces (U/N/L) are:

    height, width, sector floor level

for floors, they are:

    sector height, sector floor level, sector bounds length

for ceilings, they are:

    sector height, sector ceiling level, sector bounds length

width is taken in axial size, i.e. a slanted wall drawn with step(64,32)
would have width 64. levels are +1000 to make them all positive. Sector
bounds length is the sum of the widths (i.e. axial) of all lines surrounding
a sector, so a 64 square sector has a bounds length of 256. 

if the size parameter is:

	>0, then the surface size must equal to it
	=0, then the surface size can be anything
	<0, then the surface size must bigger than -(this parameter).

If that sounds confusing, an example should make it a lot easier:


  autotex("L",0,0,0,"BRICK6")       -- default lower tex is brick6
  autotex("L",16,0,0,"BIGDOOR6")    -- unless they are 16 high (any width),
                                    -- then we use bigdoor6 as metal strip
                                    -- (for stairs etc).
                                
  autotex("N",0,0,0,"BRICK6")       -- default wall is brick6
  autotex("N",-192,0,0,"ROCK5")     -- unless they are higher than 192,
                                    -- then they are outside rocks
  autotex("N",0,16,0,"BROWNHUG")    -- very thin walls are metal strips
  autotex("N",64,16,1032,"LITE5")   -- all 64 high 16 wide walls at
                                    -- floorlevel 32 are lights
                                
  autotex("U",0,0,0,"BRICK6")       -- default upper is brick6

  autotex("C",0,0,0,"RROCK11")      -- default ceil
  autotex("C",-192,0,0,"F_SKY1")    -- unless its very high, then its sky
  autotex("C",0,0,256,"CEIL1_2")    -- all 64 square sectors have a ceiling light

  autotex("F",0,0,0,"SLIME13")      -- default floor
  autotex("F",0,984,0,"LAVA1")      -- all floors at -16 are lava1
  autotex("F",0,1064,0,"RROCK10")   -- all floors at 64 are rrock10
  autotex("F",96,-1064,0,"SLIME14") -- all floors at 64 or higher in a 96 high
                                    -- sector are slime14


Once you are able to set up a good set of rules, you'll be able to map
very fast, because 99% of texture application will be "right" without
manual tuning. You can improve the amount of texturing you can do this
way by planning your maps styles around this feature: for example making
all rooms that require a certain floor/ceiling be at a certain height etc.


==== variables and objects

These features are here to make the language a bit more complete as a
general purpose programming language.

    set(varname, value)
    get(varname)

where varname is a string, and value can be anything. these functions
work like a set of global variables. Both return the current value.
Calling get before a set, will result in an error.

    onew

creates/returns a fresh object, with no fields in it yet. Objects are denoted
by integers, and thus pointer arithmetic is possible. Accessing an unallocated
object however results in an error.

    oset(object, fieldname, value)
    oget(object, fieldname)

Identical in behaviour to get/set, these 2 access fields in an object rather
than global variables.

See `list.h` for an example of how to use these functions to create an
actual datatype, and a caveat on the usage of "onew".

=== Custom textures


There is some basic experimental support for defining new textures.

    texture("name", 64, 128)
    addpatch("RW24_2", 0, 0)

`texture` starts a new texture definition, with the name, width and
height of the arguments you supply.

`addpatch` adds a patch onto the currently selected texture. It must be
called after at least one call to `texture`. The first argument names
the patch to be added, and the second two arguments define the x and y
offsets of the patch inside the texture.

You can switch between texture definitions and back by calling `texture`
with the same name again.

Hint: you can generate patch names using `cat`; see the file "llevels.wl"
in the WadC examples directory.

If you define at least one texture, the output WAD will contain the
definitions in a `TEXTURE2` lump.

If you have defined any new patch names, a `PNAMES` lump is also written
to the output WAD. For this to work, you have to have configured WadC to
know where your IWAD is.

=== Map type output

By default, WadC targets Doom II. Amongst other things, this means the
output map is labelled `MAP01`. To change it, use

    mapname("E1M1")

The default output format is traditional Doom format, suitable for Doom,
Doom II and Heretic. To switch to Hexen-format (also useful for Zdoom),
use

    hexenformat

This will happen automatically if you use one of `linetypehexen` or
`setthingargs` as described earlier.

    is_hexenformat

This evaluates to 1 if the map is set to hexen format, and 0 otherwise.

If you you are working on a map for a game other than Doom II, you might
find the libraries `doom.h`, `heretic.h` and `hexen.h` useful. They contain
the following helper routines to set up sensible defaults for textures, flats
and map format:

    doomdefaults
    hereticdefaults
    hexendefaults

== Pitfalls

Here are some common things that can go wrong, and which can result in
runtime errors:

- if you get a "sidedef already assigned" error, and it is not obvious
  why (the current sector looks fine), it may be the case that for a
  previously constructed sector you accidentally made a sector out of
  the whole outside of the level (by choosing the wrong side). WadC doesn't
  detect whether something is inside or outside, and this will only show
  up when defining an adjoining sector.

[[standard-library]]
== Standard Library

We really should document the standard library in this document. This is
a work in progress. The best thing to do would be to read the comments in
the `.h` files within link:../src/main/resources/include[src/main/resources/include]
to see the finer detail.

=== Basic/generic

standard.h::   very basic language & doom macros for very common
               things. Many of the macros here are easier to use
               then the builtin features they are based upon.
basic.h::      a set of higher level architectural building blocks
               based on some conventions of composing sectors. good
               to work with for bigger maps. Contains common doom map
               prefabs for things like starts, end of level, monster
               teleporting and placement, and room segments.
list.h::       lisp-style cons lists
pair.h::       pair type (useful for coordinates, etc.)
math::         some math routines (bit shifts and `pow` so far)

=== Thing definitions

heretic/things.h:: Thing definitions for Heretic
hexen/things.h::  Thing definitions for Hexen
strife/things.h::  Thing definitions for Strife

==== Doom-specific

Note that Doom and Doom II things are not yet separated out. You will need
to be careful if you are writing Doom #1 maps.

decoration.h:: macros for Doom decorations
monsters.h::   macros for Doom monsters
pickups.h::    macros for Doom pick-ups (weapons, ammo, power-ups)
spawns.h::     macros for Doom player and deathmatch starts, and teleports

=== Thing flags

`thingflags.h` contains definitions for thing flags common to all four games
(as well as Boom and MBF additions) and some routines to manipulate them. Some
of these routines were built-in commands in earlier versions of WadC:

    easy
    hurtmeplenty
    ultraviolence

any following things are available only from the said skill and upwards

    friendly

toggles the 'friendly' flag of monsters. Friendly monsters are a
http://doomwiki.org/wiki/Friendly_monster#MBF[MBF feature] and will require
an MBF-supporting port to work. It will not work for Hexen.
'friendly' defaults to off.

    setflag(x)
    clearflag(x)
    toggleflag(x)

Sets, clears or flips the given flag value, e.g. `setflag(multiplayer)`

=== Line flags

Some line flag constant values are defined in `lines.h`.

=== Other games

doom.h::       Settings and defaults for Doom/Ultimate Doom
heretic.h::    Settings and defaults for Heretic
hexen.h::      Settings and defaults for Hexen
strife.h::     Settings and defaults for Strife

The above headers are one-size-fits all for inclusion in maps for those
ports; they, in turn, pull in some smaller files in `include/<gamename>`
in some cases.

=== Port/post-vanilla

boom.h::       Boom generalised linedef function and related constants
control.h::    control sector macros, for e.g. Boom special effects
water.h::      macros for Boom-deep water special effects
zdoom.h::      macros for Zdoom-specific special effects (slopes, mirrors)