As mentioned above, modern scanner (
HSA,
Willow,
Claw,
Zooom,
Win
etc.) and oneshots (
CrazyShot,
G2,
Geist etc.) can easily beat papers. Another possibility
to resist against those nasty opponents is to create imps during the
self-replication. Even if the paper is completly stunned, the scanner will have a
hard time to kill all imps the paper leaves behind.
There are four different possibilities to achieve paper/imps:
3.1 Binary Launching Paper:
A quite convenient way to achieve paper/imps is to synchronizes three different
copies of paper to make a single on-board imp work. This can be easily done via a
binary launcher (Ref.:Imps) as the example below shows:
;name theMystery1.5 (part of it!!)
;author Paulsson
start spl 1 ;\
mov.i -1, 0 ;- make 7 processes
mov.i -1, 0 ;/
mov {ptr2, <ptr2 ; move out second paper
mov {ptr1, <ptr1 ; move out first paper
spl 3
spl 4
jmp @ptr1 ; jump to 1
mov {ptr3, <ptr3 ; move out third paper
jmp @ptr3 ; jump to 3
jmp @ptr2 ; jump to 2
pap spl step1, 0 ;\
mov.i >-1, }-1 ;\\ Normal paper, with bad constants
mov.i <-2, <1 ;// (I think I riped it from timescape :-) )
spl @0, }step2 ;/
mov.i #0, 2667 ;Impy!
ptr1 dat 5+pap, pap+5+500
ptr2 dat pap+5, pap+5+2667+500
ptr3 dat pap+5, pap+5+2667*2+500
The advantage is, that we are very flexible in choosing the paper, because
we only need to add at the end of the paper our executable imp. We can
create in this way easily numerous different and also agressive paper/imp
warrior. Beside 3 point imp-rings it is also possible to achieve mirrored
imps as shown in Cinnamon.
However, the bad side is that this technique has by far the slowest launching,
because we must first make copies of the paper before we can start them.
Fast scanners have therefor a better chance to stun these papers early enough.
If the paper is embedded in a qscanner we will also lose more often against
qscanning opponents if they launch their code faster.
A faster and smaller version of a binary launcher is used in
Blowrag as shown below:
;name Blowrag (part of it!!)
;author Metcalf/Schmidt
top mov <g3, {g3
g3 jmp bDist+iStep, imp+1
s1 spl @0, <pStep1
mov }s1, >s1
s2 spl @0, <pStep2
mov }s2, >s2
mov.i #1, <1
spl -2, <pBomb
imp mov.i #iStep, *0
pStart spl 1 ;code is starting here
spl 1
mov.i {0, #0
spl top
mov <g1, {g1
g1 spl bDist, imp+1
g2 spl bDist+2*iStep-7
mov }s1, }g2
Examples of this type are:
Blowrag,
Lord of the imp-rings II,
Safety in Numbers,
Terkonit 0.4 and
theMystery1.5
3.2 Papers containing an Imp-Launcher:
The first paper of this type was
Die Hard introduced by Paul Kline. It copies
an entire imp-launcher with each silk as shown below:
;name Die Hard (part of it!!!)
;author Paul Kline
spl 1
mov -1, 0
mov -1, 0
c0 spl @0, space
mov }c0, >c0
cs spl #0
spl imp+5334
spl imp+2667
imp mov.i #2667, *0
Strictly speaking Die Hard isn't a true paper but more like a hopper, because it
contains only one spl/mov-pair followed by a continuous 3-point launcher. The fact
that all copies still go on with executions due to the spl #0 we observe a growing
number of working imp-launcher.
Also, this is not a true spiral, but a "wimpy series of imp rings" (interleaved
imp rings, actually). The advantage, of course, is that this piece of code is very
small.
A more advanced 8-line version was later published under the same name (Die Hard) by Paul Kline.
It contains also a stone-like part bombing additionally the core. Interesting to mention is that
the bomb is copied separately from the paper.
;name Die Hard (part of it!!!)
;author Paul Kline
dvins mov 101,{1 ; pretty good bomb
dh mov dvins,dv+boot ; position dv-bomb as needed <-- start here
mov dvins,dv
spl 1,>-2002 ; make 8 processes
spl 1,>-2001
spl 1,>-2000
mov <s2,{s2 ; boot one copy of Die Hard
s2 spl c0+boot+8,c0+8
c0 spl @0,space ; here is Die Hard
mov }c0,>c0
cs spl #0 ,}dv ; following lines execute in reverse order
mov dv ,}dv+space
cb add.a #119 , dv+space
spl imp+5334 ,}dv+space
spl imp+2667 ,}dv+space
imp mov.i #2667 ,*0
A paper which achieve true imp-spiral was first created by JKW.
Mini Return of the Jedimp was one of the
first published versions, as shown below:
;name Mini Return Of The Jedimp
;author John K W
spl 1
spl 1
spl 1
evol: spl @evol, }TSTEP
mov.i }evol, >evol
evoli: spl #d2, bstep-1
mov b, >2
add.f evoli, j
j: jmp.f imp2-d2*8,{-6+bstep
b dat <1, 1
imp2 mov.i #d2, *0
It contains a modified vortex-launcher which additionally bombs the core.
Another way to achieve two different imps at the same time is the use of the
extended vortex launcher as shown below.
;name not published so far
;author Christian Schmidt
spl 1
spl 1
spl 1
spl @0, <pStep
mov.i }-1, >-1
impy spl #i3, <i7
add.f -1, 1
spl imp1-8*i3, imp2-16*i7
iSrc djn.f @-1, <dStep
imp2 mov.i #5, i7
imp1 mov.i #i3, *0
This code can easily create for example 3-pts a-imps and 7-pts b-imps at the same time.
3.3 Papers using Impstep Constants:
To create a paper which forms 3 point imp-rings (which have an imp-step of
2667) we need to find paper steps which ensure when an imp is executed, it is
followed at least sometimes by processes executing at imp+2667 and imp+2667*2.
If we take a simple silk copy copy, we can create a diagram showing where and
when each process is executed, as described by David Moore's article in Core
Warrior #68:
spl 2 ; 5 parallel processes
spl 2
spl 1
pap1: spl @0, X
mov }pap1, >pap1 ; copy
pap2: spl @0, Y
mov }pap2, >pap2 ; copy
imp: mov.i #0, 2667
| 0 1 2 3 4 5 6
----+------------------------------------------
0 | 0 1 2 3 4!
1 | 2+Y 3+Y 4+Y!
2 | 2+2Y 3+2Y 4+2Y!
3 | 2+3Y 3+3Y
4 | 2+4Y
5 | X 1+X 2+X 3+X 4+X!
6 | 2+X+Y 3+X+Y 4+X+Y!
7 | 2+X+2Y 3+X+2Y
8 | 2+X+3Y
9 | 2X 1+2X 2+2X 3+2X 4+2X!
10 | 2+2X+Y 3+2X+Y
11 | 2+2X+2Y
12 | 3X 1+3X 2+3X 3+3X
13 | 2+3X+Y
14 | 4X 1+4X 2+4X
15 | 5X 1+5X
Each row in the table represents an individual copy of the paper. Each entry
shows where a process is executing at any given time. Processes are executed
in column order; each entry will be executed in turn, top to bottom, repeated
once for each parallel process the paper has. This is followed by the same
procedure in each subsequent column.
To make a paper which generates 3 point imp-rings, we select 3 positions which
we will refer to as R, S and T, sharing the same column in the table, each
lower (and consequently executed later) than the previous. Position R should
be where an imp is executed, as indicated by an exclamation mark in the table.
Now, all we require are values for X and Y providing a solution, if one exists,
to the following equations, where R, S and T are substituted with their
corresponding entries in the table:
S = R + 2667 (2667 is the imp-step for 3 point rings in
T = S + 2667 a coresize of 8000, since 2667*3 = 8001)
For example, after selecting the processes at rows 0, 1 and 2 of column 4, we
can show Y must be equal to 2668 for imp-rings to form. This is the sequence
employed by Return of the Fugitive:
(3+Y) = (4) + 2667
(2+2Y) = (3+Y) + 2667 -> Y = 2668
By selecting the processes at rows 2, 6 and 9 of column 6, we show Y must be
equal to X - 2667 for imp-rings to form. This sequence is used by both The
Fugitive and Cinammon:
(4+X+Y) = (4+2Y) + 2667
(4+2X) = (4+X+Y) + 2667 -> Y = X - 2667
At least 4 other sequences which allow imp-rings to form exist. However, these
appear to be less effective than the two illustrated above, which were chosen
for use by David Moore in his two Fugitives.
A big advantage is also that we are free in choice of the impstep. You want 7
point imps? No problem, just use 1143 instead of 2667. Other impsteps are also
possible as described more detailed in the following Chapter 3.4.
Examples of this type are:
The Fugitive and
Return of the Fugitive.
3.4 Papers containing Silk-Imps:
Well, this way to achieve paper/imps isn't as tricky as it looks like from the first glance. I am sure anyone will immediately recognise the missing of the well known imp constants, like 2667 or 1143. Well, for 3-point or 7-point imps we really need this values, but we aren't talking now about such 'small' imps. We have learned in the prior Chapter 3.3 how the last silk-pair creates the pattern for a successfull imp-ring. But are we really limited just to 3-point or 7-point imps with all those numerous copies the paper creates during the battle? No, we aren't. In general we could make any kind of imps. You want a 91-point imp? Well, shouldn't be a problem. But it isn't really neccessary to calculate a constant for a special n-point imp. Every kind of stepsize could give us an appropriate imp. In that sense it is then trivial to know how much points the imp has.
But one must also keep in mind, that it takes really a loooong time until such a imp-spiral is formed. But however, with all the numerous copies of the paper the spiral generation isn't really neccessary. The imp will usually survive until the end of the battle. In this context we must say goodbye to the well defined situation as found in an imp-launcher. Below is a simple example which demonstrate the functioning. Try different values for pStep1 and watch how the programm works via the graphic modus in pmars:
pGo spl 1, <4000
mov -1, 0
pap1 spl @0, <pStep1-1
mov }pap1, >pap1
mov.i #1, pStep1
One must further know, that imps having plenty of points are much more vulnerable than 3-point or 7-point imps. Because the spiral is much more sensitive and can be much more easy disrupted. So, why discussing this if it doesn't strengths a paper? Because, we can use them for our offensive. You will understand this later, after we have discussed the following basics.
First, let's take a look to the following imp:
mov.i #value, 1
I don't explain how it works, that should be clear. But one must mention that it copies itself regardless of what kind of instruction it will thereby overwritten. Because it uses a direct adressing mode. But we can also achieve imps using an indirect adressing mode. For example:
mov.i #value, *1
And of course we could also use postincrement indirect adressing mode:
mov.i #value, }1
So long as you let them run alone they will act like a normal imp. With a non-zero a-field the second run through the core will look different because then it copies to the location where its own a-field pointed to. But that's not a problem because the whole core is filled at this time with mov's. But due to the indirect mode it will be much more vulnerable against an opponent, because if it reaches for example a dat with a non-zero a-field it will copy itself to the location where the dat's a-field pointed, increment the a-field of the dat and then finally dies.
For the above example it is fatal, because we have just one working process. But if we integrate that in a paper it would generate a huge numbers of running postincrementing indirect adressed imps. As explained above, they won't run well defined through the core but would also 'bomb' everything the a-fields in front of the imp is pointing to and increment them. Only the huge amount will let them survive until the end of the battle.
Coming back to the first example, we would then have something like:
pGo spl 1, <4000
mov -1, 0
pap1 spl @0, <pStep1-1
mov }pap1, >pap1
mov.i #-(pStep1)*n, }pStep1
An advantage in that context is, that we are running paralell processes. The imp doesn't copy itself to just one location but to three different because of the postincementing. In the case of a paper which runs 8 paralell processes it will generate 8 mov's per copied paper and every further executed mov due to the imp-run will create again further one. The core will be overflowed by mov's which acts as imps but also 'bombs' and increment everything they reach.
The a-field of the indirect adressed imp points back to a previous copy. This additionally assists the survival of the imps. n could be 2 or higher.
One of the first papers using this technique was Paul Kline's
retinA, which was also found in
RetroQ.
Seven, another paper of this type is shown below:
;name Seven (part of it!!)
;author John Metcalf
pGo: spl 1, <4000
spl 1, <2000
pap1:spl @0, <pStep1
mov }pap1,>pap1
mov }pap1,>pap1
pap2:spl @0, <pStep2
mov }pap2,>pap2
mov {pap2,<pap3
pap3:spl @0, >pStep3
mov.i #pStep2-pStep3+1,}pStep3-1
3.5 Mixed Strategies:
One could also combine different ways to achieve paper imps or using different imps inside a paper.
Cinammon for example produces imps with two different techniques. Imp-ring forming paper steps are used to generate 3-point rings, while mirrored-imps are created by binary-launching the paper. It expands on this with the addition of silk-imps.
ppGo:mov {pap1, {bb ; binary launch
mov {pap1, {bb
bb: spl pap1+4000+12,{qf+25*qs
pap1:spl @12, >pStep1
mov }pap1, >pap1
mov }pap1, >pap1 ; copy
pap2:spl @0, >pStep2
mov }pap2, >pap2 ; copy
pap3:spl @0, >pStep3
mov }pap3, >pap3 ; copy
mov.i #-2669, }4000-pStep3 ; silk-imp
mov.i #-pStep2, 2667 ; standard-imp
mov.i #4001, *0 ; mirrored-imp