I use PlainTex because I like its simplicity and because I understand almost all lines of its code. When I look at the output routine of LaTeX I only understand a little bit.
So I trie to add floats on my own to PlainTex, my first trial can be seen here: How to keep the order of floats in Plain TeX?
I would like to get a similar float handling as in LaTeX but with the possibility to understand the code. As there is no documentation for more complex output routines I have a question now.
Look at my MWE:
% Plain LuaTeX (for other engines: \protected\def\glet{\global\let})
\font\testfont=cmr17 at 20 pt% to show the problem better
\testfont
\normalbaselineskip24pt
\normalbaselines
\catcode`\@=11
\parskip\z@
\raggedbottom
% The sizes have to be calculated in \output.
\newdimen\fullhsize
\newdimen\fullvsize
\fullhsize\hsize
\fullvsize\vsize
\newdimen\@colroom
\@colroom\fullvsize
% Float boxes as in latex.ltx
\newinsert\bx@A
\newinsert\bx@B
\newinsert\bx@C
\newinsert\bx@D
\newinsert\bx@E
\newinsert\bx@F
\newinsert\bx@G
\newinsert\bx@H
\newinsert\bx@I
\newinsert\bx@J
% Float handling parameters:
\newcount\@topnum
\newcount\maxtopnum \maxtopnum\thr@@
\newdimen\@toproom
\newdimen\maxtoproom \maxtoproom.4\fullvsize
\newcount\@botnum
\newcount\maxbotnum \maxbotnum\tw@
\newdimen\@botroom
\newdimen\maxbotroom \maxbotroom.3\fullvsize
\newif\if@insert
\newif\if@trybottom
\def\@empty{}
% Similar to latex.ltx:
\def\@freelist{\bx@A\bx@B\bx@C\bx@D\bx@E\bx@F\bx@G\bx@H\bx@I\bx@J}
\let\@toplist\@empty
\let\@botlist\@empty
\let\@deferlist\@empty
% List handling macros:
\def\@additem#1#2{%
\expandafter\gdef\expandafter#1\expandafter{#1#2}}
\def\@takefirstitem#1{%
\expandafter\@@takefirstitem#1!%
\glet#1=\@tempa}
\def\@@takefirstitem#1#2!{\gdef\@currbox{#1}%
\def\@tempa{#2}}
% A primitive definiton of a float:
\def\float#1{% #1=1 -> top float, 2 -> top or bottom float, 3 -> bottom float
\@takefirstitem\@freelist
\global\count\@currbox#1\relax
\global\setbox\@currbox\vbox\bgroup
\parskip\z@}
\def\endfloat{\par\vskip\z@\egroup
\penalty-40000\relax
\dimen@\prevdepth
\vbox{}
\prevdepth\dimen@
\penalty-30000\relax}
\def\@nextboxcnt{% type of the next float on deferlist
\expandafter\expandafter\expandafter
\count\expandafter\@firstofmany\@deferlist!}
\def\@nextboxht{% height of the next float on deferlist
\expandafter\expandafter\expandafter
\ht\expandafter\@firstofmany\@deferlist!}
\def\@firstofmany#1#2!{#1}
% Output routine
\output{\myoutput}
\def\myoutput{%
\ifnum\outputpenalty=-40000\relax
% \ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
\global\setbox\@ne\vbox{\unvbox\@cclv}%
\else
\ifnum\outputpenalty=-30000\relax
\setbox8\box\@cclv
\unvbox\@ne
\ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
%\unvbox\@cclv
%
\ifcase\count\@currbox\or%1 top float
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@ \ifdim\maxtoproom<\dimexpr\@toproom+\ht\@currbox\relax \@insertfalse\fi\fi
\if@insert
\expandafter\@additem\expandafter\@toplist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@toproom\ht\@currbox
\global\advance\@topnum\@ne
\else
\expandafter\@additem\expandafter\@deferlist\@currbox
\fi
%
\or%2 top or bottom float
\@inserttrue
\@trybottomfalse
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@
\ifdim\maxtoproom<\dimexpr\@toproom+\ht\@currbox\relax \@insertfalse\fi\fi
\if@insert
\expandafter\@additem\expandafter\@toplist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@toproom\ht\@currbox
\global\advance\@topnum\@ne
\else
\ifx\@deferlist\@empty \@trybottomtrue
\else \expandafter\@additem\expandafter\@deferlist\@currbox\fi
\fi
%
\if@trybottom
\@inserttrue
\ifdim\ht\@currbox>\@colroom \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\ht\@currbox\relax \@insertfalse\fi\fi
\if@insert
\expandafter\@additem\expandafter\@botlist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@botroom\ht\@currbox
\global\advance\@botnum\@ne
\else
\expandafter\@additem\expandafter\@deferlist\@currbox
\fi
%
\fi
%
\or%3 bottom float
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifdim\ht\@currbox>\@colroom \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\ht\@currbox\relax \@insertfalse\fi\fi
\if@insert
\expandafter\@additem\expandafter\@botlist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@botroom\ht\@currbox
\global\advance\@botnum\@ne
\else
\expandafter\@additem\expandafter\@deferlist\@currbox
\fi
%
\fi
%
\else
\shipout\vbox{\makeheadline\pagebody\makefootline}%
\advancepageno
% Prepare next page/column:
\global\@colroom\fullvsize
\global\@topnum\z@
\global\@toproom\z@
\global\@botnum\z@
\global\@botroom\z@
%
\ifx\@deferlist\@empty\else
% Top floats
\loop
\@inserttrue
\ifnum\@nextboxcnt<\z@ \@insertfalse\fi
\ifnum\@nextboxcnt>\tw@ \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@
\ifdim\maxtoproom<\dimexpr\@toproom+\@nextboxht\relax \@insertfalse\fi\fi
\if@insert
\@takefirstitem\@deferlist
\expandafter\@additem\expandafter\@toplist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@toproom\ht\@currbox
\global\advance\@topnum\@ne
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\fi
%
\ifx\@deferlist\empty\else
% Bottom floats:
\loop
\@inserttrue
\ifnum\@nextboxcnt<\tw@ \@insertfalse\fi
\ifdim\@nextboxht>\@colroom \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\@nextboxht\relax \@insertfalse\fi\fi
\if@insert
\@takefirstitem\@deferlist
\expandafter\@additem\expandafter\@botlist\@currbox
\global\advance\@colroom-\ht\@currbox
\global\advance\@botroom\ht\@currbox
\global\advance\@botnum\@ne
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\fi
%
\ifnum\outputpenalty=-\@MM \dosupereject\fi
\fi
\fi
\ifnum\outputpenalty<-30000\relax
\global\vsize\maxdimen\else\global\vsize\@colroom\fi}
\def\pagebody{\vbox to\fullvsize{\boxmaxdepth\maxdepth \pagecontents}}
%\pagecontents that insert top and bottom floats:
\def\pagecontents{\ifx\@toplist\@empty\else
\loop
\@takefirstitem\@toplist
\expandafter\@additem\expandafter\@freelist\@currbox
\box\@currbox
\unless\ifx\@toplist\@empty\repeat
\fi
%
\dimen@=\dp\@cclv \unvbox\@cclv % open up \box255
%
\ifx\@botlist\@empty\else
\loop
\@takefirstitem\@botlist
\expandafter\@additem\expandafter\@freelist\@currbox
\box\@currbox
\unless\ifx\@botlist\@empty\repeat
\fi
\ifvoid\footins\else % footnote info is present
\vskip\skip\footins
\footnoterule
\unvbox\footins\fi
\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
1. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
\float1 ABCD1 \vskip20pt\endfloat
\float1 ABCD2 \vskip20pt\endfloat
\float1 ABCD3 \vskip20pt\endfloat
\float1 ABCD4 \vskip20pt\endfloat
\float1 ABCD5 \vskip20pt\endfloat
\float1 ABCD6 \vskip20pt\endfloat
2. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.%
\float1 ABCD7 \vskip20pt\endfloat% disappears
\float1 ABCD8 \vskip20pt\endfloat
3. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
4. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
5. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
\bye
As you can see in the picture the 7th float disappears. This is a known problem near pagebreaks. I know that LaTeX fixes this by adding 2 penalties. I tried this, too, with \penalty-40000 but without success.
What am I doing wrong?
(Edit: a better output routine, same result.)

-40000really isn't any more effective than-10000. – barbara beeton Sep 16 '19 at 02:42\penalty-10004 \vbox{} \penalty-10003after a float in vertical mode so that floats near a page break are not lost. But this cannot be all because my MWE does not work. But the code inlatex.ltxcontains so much macros, so I am not able to identify the relevant code lines. – Weißer Kater Sep 16 '19 at 20:33What to do? Note if the @currbox is emptied in the output routine or not.
– Udo Wermuth Sep 17 '19 at 22:18In general a penalty of -10000 triggers the output routine, but you can use other values to indicate why the output routine is called. You use -30000 for your float environment. A value of -40000 does not make a difference. But you can use -10001 if you have something else than \float and you want to do something special in the output routine. So you should really use -10001 instead of -30000.
– Udo Wermuth Sep 17 '19 at 22:20\newinsertbecause I need the\boxand the\count. Yes, of coure I can write\penalty-10001instead of\penalty-30000but what is the difference? – Weißer Kater Sep 18 '19 at 19:38\ifnum\outputpenalty>-20000\else\dosupereject\fi. You changed that code too, so it is not a problem with -30000.But your code doesn't work if you add four additional
– Udo Wermuth Sep 19 '19 at 06:57\floatlines just above the\bye. The last one is not output. The\dosuperejctmust do more.\dosuperejectist my next project... Then floats that are allowed to be placed where they are called and multicolumn output with dblfloats and a float barrier. There is still much to do and of course I could use LaTeX but I want to do it on my own. So I have the chance to understand the code. LaTeX has so many macros without a documentation. – Weißer Kater Sep 19 '19 at 08:42\count\bx@A. Not directly but in my definition of\floatthe is the line\global\count\@currbox#1\relax. It is set to 1 for a top float, 2 for a flexible (top or bottom) float and 3 for a bottom float. – Weißer Kater Sep 19 '19 at 08:45