Railway station with one main line and one branch line in Railway Empire 2

To connect a branch line to a main line at a railway station in Railway Empire 2, create a station with four platforms. In the example below the mainline is on the left side on tracks #1 and #2, the branch line arrives to tracks #3 and #4 at the bottom from the right. 

Connect the branch line to the station

To allow any train to reach any track, we will place a four track gridiron where the branch line arrives.

  • Run the four tracks long enough parallel to leave enough room for the four track gridiron. The two white dots indicate the approximate length of the four track gridiron.
  • Make sure the number of tracks is set to Max
  • Place the gridiron on the four tracks

Connect tracks #3 and #4 to the main line

At the top we will connect tracks #3 and #4 to the main line, so the branch line trains can continue on the main line, and main line trains on the branch line.

Place two 2 track gridirons on the tracks

We will place two separate 2 tracks gridirons, one on tracks #1 and #2, and another on tracks #3 and #4. A four track gridiron would also work, but it requites twice as long parallel tracks.

  •   Place a two track gridiron on the main line
  • Extend track #3 to leave room for the other two track gridiron.
  • Right-click to terminate the track without connecting it to anything
  • Click the Build button
  • Extend track #4 too.
  • Set the gridiron size to 2
  • Place the other two track gridiron on tracks #3 and #4

Connect tracks #3 and #4 to the main line

  • Select the Demolish icon
  • Trim tracks #3 and #4 to the gridiron

  • Connect track #3 to track #1
  • Track #4 to track #2

Set the track directions

  • Select the Track Direction button
  • Set the direction of the tracks

 

Getting started with Railway Empire 2

Configuration

– Automatic Pause stops the game when we open the track building panel. This prevents traffic jams, but stops the game and progress unnecessarily.
– When the window loses focus the game and progress stops.
– Edge scrolling is very fast and sensitive in Railroad Empire 2. To disable automatic edge scrolling.

  • On the Controls tab select
    • Off for Automatic Pause
    • Off for Pause when Window Loses Focus
    • LMB + Drag for Mouse Scrolling

– It is helpful to see the topography during track construction.

  • On the Display tab set
    • Topography Map During Track Construction to On

– After a while opponents regularly repeat the same insults, at least we can silence them.

  • On the Sound tab set the volume of
    • Voices to 0
  • Click the Back button

Troubleshooting

If the game or the tutorial stops advancing

Check if the game is paused

By default the game automatically pauses and stays in pause mode when you open the track construction panel. In this state even the tutorial stops responding. We can turn off Automatic Pause on the Controls tab of Options (see Configuration above).

Make sure
  • The round pause button indicates the paused game.
  • Click the round button to start the game. The arrow indicates the running game.
  • Click the button again to speed up the game

The expected freight type is not yet transported

  • In the transfer tutorial you need to wait until all expected freight type is transferred

The city is not growing

An industry in the city grows if the demand is at least 60% satisfied.

Goods don’t arrive

Your main city needs a type of goods

Another city supposed to produce and send it, but for the industry to activate the population has to reach a minimum level

  • Satisfy the current demands of the small city to promote growth, so it will produce the needed goods for your main city.

No demand for the goods

When you try to add a new station to a line, and the directly connected cities do not need the type of good it supplies, the message appears:

According to the settings you made, your train line cannot perform any actions at the station of …

You should check the settings so that the trains do not have to make unnecessary stops.

To help to distribute the goods to other cities, create a warehouse at a station which has another lines, and add the types to the warehouse on that station:

Issues during track building

This station cannot be reached from the previous station and therefore can not be added to the list.

The trains cannot switch between tracks to make the round trip between the stations.

  • Place a station gridiron on the tracks close to the station for the trains to be able to switch between the tracks.

Building a new rail line

Build a station

When you connect the first track to the station the track you use determines the size and cost of the platforms. For rural stations use the first two tracks closest to the building to minimize the cost.

Build the tracks

  • Make sure to place grid irons to each station to allow trains to switch tracks, and set the direction of the rails.
  • Add supply towers to each line

Create a new rail line

  • Open the new real line panel
  • Select the stations of the line
  • Select the locomotive and click the Confirm button

Freight transfer between lines

To transfer freight between lines in cities and rural stations those have to have a warehouse. The transfer happens if there is no direct rail, and the way by rail is at most twice as long as the direct way by road. 

Warning: The warehouse does not supply the place where it is placed. Its only purpose is to supply the connected cities, so the hosting city will not get from the stock. Use the warehouse only for goods which are not needed in that city, or set up a separate freight station to supply the city with lines from the suppliers.

To keep the freight type for the city

  • Remove the type from the warehouse

To prevent a line carrying a freight type

  • Select the line
  • Edit the line
  • Hover above the station name and click the Edit Station button
  • The first click on the good type sets it to high priority (green arrow), the second click prevents the transfer (red sign). The third click clears the marks.

If you still need a warehouse

Research the warehouse
  • Click the research button
  • Drag the timeline with the left mouse button to 1830
  • Click the warehouse button to unlock it
  • Click the checkmark to unlock the development
  • Close the Research panel in the upper right corner
Add the warehouse to the station
  • Select the train station
  • Select the station and click the Construct Extension button
  • Click the Warehouse button and click the checkmark at the bottom of the panel
Specify the type of goods the warehouse can transfer

Warning: the selected good types will not supply the place hosting the warehouse, only places with connected rail lines!

  • Select the Warehouse button
  • Select the goods the warehouse can transfer. Click the trash can to remove a type.
  • Click the X in the upper right corner of the station panel to close all station related panels

Passenger and mail transfer between lines

Passengers and mail can transfer between lines in cities, but rural stations have to have a hotel.  The transfer happens if there is no direct rail, and the way by rail is at most twice as long as the direct way by road.

 Research the hotel

  • Click the research button
  • Drag the timeline with the left mouse button to 1840
  • Click the hotel icon to unlock it
  • Close the research panel in the upper right corner

Add the hotel to the station

  • Select the station and click the Construct Extension button
  • Select the Hotel button and click the check mark at the bottom of the panel

Game play

To make the game more relaxing

Disable mergers before starting the game

If another company acquires 100% of your stocks, the game is over. To remove this possibility disable mergers.

Optimize staff

When in one area more than 50 employees work for you, start to optimize your staff.

 

Transporting goods

Perishable

If you place refrigerator cars on the line the revenue of meat, vegetables, fruits, milk and dairy products increases by 25%.

 

Prevent scrolling in Lucid Charts embedded viewer

When a Lucid Chart image is embedded in a web page, the Lucid viewer allows the accidental scrolling and zooming of the image. Currently, there is no option to disable these features.

There is a simple way to prevent accidental interaction with the Lucid Chart viewer. We can place a transparent layer on top of the image to isolate it.

  • Create a 1 x 1 pixel transparent png file: transparent-1_1.png
  • Enclose the embedded chart in a parent DIV and place the transparent layer on top of it
  • Set the width and height in the parent DIV, and use ” width: 100%, height: 100% ” in the transparent IMG and the IFRAME code to match all sizes

This syntax is for Remix React.js, which uses {{ }} around the style elements, but it should be easy to reformat it for regular CSS

<div style={{width: '960px', height: '720px', margin: 'auto', position: 'relative'}}>
  <img src="transparent-1_1.png" style={{width: '100%', height: '100%', position: 'absolute'}}/> 
  <iframe allowFullScreen frameBorder="0" style={{width: '100%', height: '100%'}} src="https://lucid.app/documents/embedded/MY_GUID" id="MY_ID">
  </iframe>
</div>

How to turn off the NSFW filter in Stable Diffusion

When the Stable Diffusion AI image generator creates pictures, it sometimes flags ordinary outputs as Not Safe For Work (NSFW). If you use the software at home on your personal computer you may disable the NSFW filter.

When you clone the Stable Diffusion GitHub repository, the txt2img.py file should appear in the scripts directory. If it is not there, clone the repository again from https://github.com/CompVis/stable-diffusion.git

  • Open the scripts/txt2img.py file in a text editor
  • Add a new first line to the check_safety function to immediately return the original image and an empty string without checking. Leave the rest of the function as is, as it will not be executed.
def check_safety(x_image):    return x_image, ' '
    safety_checker_input = ...

ImportError: cannot import name ‘CLIPTextModelWithProjection’ from ‘transformers’

When Stable Diffusion throws the following error

 

ImportError: cannot import name ‘CLIPTextModelWithProjection’ from ‘transformers’

  • Open the environment.yaml
  • Change the version number of the transformers to
    - transformers==4.31.0
  • Update the environment with
    conda env update -f environment.yaml

Installing Stable Diffusion AI image generator

Install the Git client

Install Miniconda 3

Clone the Stable Diffusion GitHub repository

  • Cerate another directory on the same level: stable-diffusioncd

Download the latest Stable Diffusion checkpoint

Configure the Python environment with Miniconda

  • Start Miniconda from the Start Menu
  • In the Miniconda terminal execute the following lines
    • Create the ldm Python environment
      conda env create -f environment.yaml
      • this will cerate the Conda environment files at C:\Users\MY_USER_NAME\.conda\envs
        If anything goes wrong during the environment creation, delete the ldm folder and run this command again.
    • Activate the just created environment
      conda activate ldm

Copy the checkpoint file into the models directory

  • Open a terminal in the stable-diffusion directory
  • Create a directory for the model
    mkdir models\ldm\stable-diffusion-v1
  • Step into the new directory
    cd models\ldm\stable-diffusion-v1
  • Copy the downloaded .ckpt file into the models\ldm\stable-diffusion-v1 directory and rename it to model.ckpt
    copy C:\Users\MY_USER_NAME\Downloads\sd-v1-4-full-ema.ckpt model.ckpt

To use Stable Diffusion

Activate the Python environment

  • Start Miniconda 3 from the start menu
  • In the terminal navigate to the stable-diffusion directory
  • Activate the ldm Anaconda environment
    conda activate ldm

Generate the image

We will call a Python script with the –prompt argument and type the English description of the image

python scripts/txt2img.py --prompt "a close-up portrait of a cat by pablo picasso, vivid, abstract art, colorful, vibrant" --plms --n_iter 5 --n_samples 1

The image will be created in the stable-diffusion\outputs\txt2img-samples\samples directory

Arguments

To get help on using Stable Diffusion execute
python scripts/txt2img.py --help

  • –plms specifies how images are sampled
  • –n_iter 5 sets the number of iterations
  • –n_samples 1 – the nmber of samples generated

For more information see https://www.howtogeek.com/830179/how-to-run-stable-diffusion-on-your-pc-to-generate-ai-images/

Creating Remix (React.js) web applications

Remix has an HTML first, simple data access philosophy. Most Remix web applications work without JavScript code in the browser. It is possible to create a complete dynamic data driven Remix web application with only server side JavaScript code with pure HTML in the browser.

About Remix

This back to the roots approach makes Remix applications easy to understand, extend, and troubleshoot. A single TypeScript file contains the database access (backend) and the browser side (frontend) code. The data transfer API setup between the server and the browser is handled entirely by the Remix framework, only a few lines of code is needed to access the data in the browser.

The loader() function reads the data from the database and exposes it in JSON format to the browser. We can even expose environment variables to the browser, but make not to send secret values, as those are accessible to the user.

In the browser side code we use “|| {}” to avoid TypeError: Cannot destructure property ‘incidents’ of ‘useLoaderData(…)’ as it is null.

// /app/routes/_index.tsx file

import { useLoaderData } from '@remix-run/react';
import { LoaderArgs, json } from "@remix-run/node";

// --------------------------------------

// The server side code
export async function loader({ request }: LoaderArgs) {

  ...
  const data = await GET_THE_DATA_FROM_THE_DATABASE();
  ...
  // Expose the data to the browser
  return json({ environment: process.env.ENVIRONMENT, data: data });

}

// --------------------------------------

// The browser side code
export default function Index() {

  const { environment, data } = useLoaderData<typeof loader>() || {} ;

  return (
    <>
      Environment: {environment.environment}
    </>
  )

}

To create a new Remix web application

The official instructions are at Remix Quickstart

To start the development of a new Remix React.js web application

  • Create a new directory for the project
  • Create the .gitignore file
  • Open a terminal in the project directory and initialize a new Remix project. To learn about the Remix templates visit Remix Stacks. We will use the basic structure without any template.
    npx create-remix@latest MY_PROJECT_NAME
    • Answer y to the question
      Need to install the following packages:
      create-remix@1.19.3
      Ok to proceed? (y)
    • Select Just the basics and hit enter for the question
      What type of app do you want to create?
    • Select Remix App Server for the question
      Where do you want to deploy?
    • Select TypeScript and press enter for the question
      TypeScript or JavaScript?
    • Answer Y for the question
      Do you want me to run npm install?

Test the Remix web application

  • Open a terminal and navigate into the web application directory
  • Start the web server
    npm run dev
  • In the web browser navigate to http://localhost:3000/

Styles

There are multiple ways to reference style sheets in React, we will combine them to be able to use a global style sheet for the overall look and feel of the site and load additional page specific sheets.

  • Create the /app/styles directory for the style sheets
    mkdir app/styles
  • Create the /app/styles/global.css style sheet file
/* /app/styles/global.css file */

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

html,
body {
  max-width: 100vw; 
  font-family: Roboto, Helvetica, Arial, sans-serif;
}

a {
  color: inherit;
  text-decoration: none;
}

/* =========================================================== */

/* BEGIN Loading indicator fade in */

.fade-in-image {
  background-color: white;
  animation: fadeIn 5s;
  -webkit-animation: fadeIn 5s;
  -moz-animation: fadeIn 5s;
  -o-animation: fadeIn 5s;
  -ms-animation: fadeIn 5s;
}

@media (prefers-color-scheme: dark) {
  .fade-in-image {
    filter: invert(100%);
  }
  .fade-in-image h1 {
    color: black;
   }
}

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
@-moz-keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
@-webkit-keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
@-o-keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
@-ms-keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

/* END Loading indicator fade in */

/* =========================================================== */

/* BEGIN Menu */

.navlink {
  margin: 7px;
  margin-left: 20px;
  float: left;
  color: #f0f0f0;
}

#navbar a.pending {
  color: gray;
}

#navbar a.active {
  color: white;
  font-weight: bold;
}

/* END Menu */

/* =========================================================== */

/* BEGIN Page content */

.pagecontent {
  margin-left: 20px;
  margin-right: 20px;
}

/* END Page content */
  • Update the /app/root.tsx file to load the global and page specific style sheets for every page. We also define the common title and favicon values for the entire site.
// /app/root.tsx file

import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";

// ========================================

// Import the global style sheet
import styles from "~/styles/global.css";

// Import the LinksFunction
import type { LinksFunction } from "@remix-run/node";

// Expose the imported stylesheet to the <Links /> module
export const links: LinksFunction = () => {
  return [
    {
      rel: "stylesheet",
      href: styles,
    },
  ];
};

// ========================================

// The <Links /> component will create the <link ... HTML instruction in the <head> of all pages to load the style sheet
export default function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <title>MY APPLICATION NAME</title>
        <meta name="description" content="MY APPLCIATION DESCRIPTION" />
        <link rel="icon" href="/favicon.ico" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

Menu

To be able to navigate between pages we will create a menu system. To code it only once and use it in every page, we will create the Header component in its own file, and call it from every page of the application. In this example we will use Material UI and React components. After the </AppBar> instruction we will also add a loading indicator which automatically fades in when the page load takes a longer time.

  • Install the React and MaterialUI Node.js libraries. In the terminal execute
    npm install @mui/material @emotion/react @emotion/styled
  • Download or create an animated loading indicator gif image and save it in the /public directory and name it Loading_icon.gif
  • Create the _header.tsx file in the /app/routes directory
// /app/routes/_header.tsx file

// Remix imports
import { NavLink, useNavigation } from '@remix-run/react';

// Material UI imports
import AppBar from '@mui/material/AppBar';

// Cascading menu
import * as React from 'react';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';

// Export the function to make it available to other modules
export default function Header(environment:any) {
  
  // ----------------------------------------------------
  // Loading indicator
  const navigation = useNavigation();
  const isLoading = Boolean(navigation.state === 'loading');

  // ----------------------------------------------------
  // Cascading menu

  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const open = Boolean(anchorEl);
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setAnchorEl(null);
  };

  // ----------------------------------------------------

  return (
    <>
      <div style={{width: '100%', backgroundColor: '#6ba4ab'}}>
        <a
          href="./"
          rel="noreferrer"
        >
          <img src="MY_HEADER_IMAGE.png" style={{width: '100%'}} />
        </a>
      </div>
      
      <AppBar id="navbar" position="static" style={{ display: 'inline-block', backgroundColor: '#6ba4ab'}} >

        <div className="navlink">
          <NavLink
            to="/" end
            className={({ isActive, isPending }) =>
              isPending ? "pending" : isActive ? "active" : ""
            }
          >
            Home
          </NavLink>
        </div>

        {environment.environment != 'production' ?
          <div className="navlink" style={{margin: '0', marginTop: '6px', marginLeft: '12px'}}>
            <Button
            id="diagrams-button"
            aria-controls={open ? 'basic-menu' : undefined}
            aria-haspopup="true"
            aria-expanded={open ? 'true' : undefined}
            onClick={handleClick}
            sx={{color: '#f0f0f0', textTransform: 'none', fontFamily: 'Roboto, Helvetica, Arial, sans-serif', fontSize: '1rem', lineHeight: '1', letterSpacing: '0em'}}
            >
              MY CASCADING MENU ITEMS
            </Button>
            <Menu
              id="basic-menu"
              anchorEl={anchorEl}
              open={open}
              onClose={handleClose}
              MenuListProps={{
                'aria-labelledby': 'basic-button',
              }}
              sx={{}}
            >

              <MenuItem onClick={handleClose}>
                <NavLink
                  to="/physical-supply-chain"
                  className={({ isActive, isPending }) =>
                    isPending ? "pending" : isActive ? "active" : ""
                  }
                >
                  MY CASCADING MENU ITEM NAME
                </NavLink>
              </MenuItem>

            </Menu>
          </div>
        :
          null  
        }

        <div className="navlink">
          <NavLink
            to="/about"
            className={({ isActive, isPending }) =>
              isPending ? "pending" : isActive ? "active" : ""
            }
          >
            About this site
          </NavLink>
        </div>

      </AppBar>

      { isLoading ? <div className="fade-in-image" style={{position: 'absolute', zIndex: '100', width: '100vw', height: '100vw'}}><h1 style={{position: 'absolute', top: '20px', left: '100px'}}>Loading data ...</h1><img src="Loading_icon.gif"/></div>
      :
        null
      }

    </>
  )
}

Add the menu to the home page

  • Update the /app/routes/_index.tsx file to call the header and display the menu and remove the sample links:
// /app/routes/_index.tsx file

import type { V2_MetaFunction } from "@remix-run/node";
import Header from "./_header";

export const meta: V2_MetaFunction = () => {
  return [
    { title: "New Remix App" },
    { name: "description", content: "Welcome to Remix!" },
  ];
};

export default function Index() {
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>

      {/* Display the Header component */}
      <Header />

      <div className="pagecontent">
        Hello
      </div>

    </div>
  );
}

Footer

In the next post we will display the version and the name of the envionment in the footer, so let’s create it with that in mind.

  • Create the /app/routes/_footer.tsx file
// /app/routes/_footer.tsx

// Pass the environment variable as 
// <Footer environment={environment} />

// Export the function to make it available to other modules
export default function Footer(props:any) {

  // React uses camelCase for CSS properties
  return (
    <>
    <div className="footer" style={{marginLeft: '20px'}} >
      Version: 2023-09-07_01 {props.environment}
    </div>
  </>
  );
}

ERROR: relation “…_seq” does not exist

PostgreSQL has three auto increment column types:

  • SMALLSERIAL
  • SERIAL
  • BIGSERIAL

The pdAdmin 4 user interface unfortunately generates the wrong CREATE script for existing tables:

CREATE TABLE IF NOT EXISTS public.test (
    id integer NOT NULL DEFAULT nextval('test_id_seq'::regclass)
)

If we execute it, we get the error message:

ERROR: relation “test_id_seq” does not exist
LINE 3: id integer NOT NULL DEFAULT nextval(‘test_id_seq’::regcl…

The correct syntax which auto generates the sequence too, is:

CREATE TABLE public.test (
   id SERIAL PRIMARY KEY
);

For more information see Creating tables with PostgreSQL