Monthly Archives: March 2023

Horde Plus Gamemode Mod (Discontinued)

I was writing this when the mod was still active.

Horde Plus Gamemode is based on Mordhau Vanilla Horde Gamemode but has Modified/New Elements. Previously, I used to make Sumerian Horde Gamemode. But the structure was very dirty because it was my early modding experiment. I wanted to start from scratch.

This mod is aiming for three things. Stability, Minimal Filesize and My Personal Appetite.

Stability. I’ve added features that just work as intended. (This means that some of my ideas were not able to be with the mod after the tests.) You may face some glitches like chest gambled items are being eaten by the earth, enemies stuck at certain points and more… They are all transplanted from Vanilla Horde. But I have tried to fix bugs like stuck points.

Minimal Filesize. My own server has somehow an extremely slow mod download speed when it is launched. It is quite an annoying task to manually download large mods with frequent updates. I therefore began to use only vanilla resources to have a very small file size. Downloading entine Horde Plus Gamemode Mod takes less than 512 KB.

My Personal Appetite. As a fellow normal Mordhau player, I wanted to modify some assets and add features to Vanilla Horde Gamemode. Also wanted to bring some features from my favorite games like ‘Classic Diablo II’ and ‘Elder Scrolls Series’.

Modified/New Systems

  • Players have some perks from the beginning.
    • Fireproof : Reduces incoming fire damage.
    • Flesh Wound : If you die to something other than a headshot or environmental damage, you stay alive for another 5 seconds.
  • Disabled kicking AFK players. You can check your boiling pot or empty your stomach without being kicked.
  • Every blunt Iron/Steel weapons deal chip damage on blocked when perform a swing attack.
  • Adjusted Wave clear reward gold amount
  • Adjusted Armor Costs, Random Chests Items
  • Shielded Enemies receive more damages.
  • Yeets and Ninjas will be killed with a single hit.
  • Modified Bosses
  • Added Custom Bosses, Minions
  • Some bosses will drop their Unique weapons(◎) on death.
  • Purchasable ranged weapons ammos are removed.
  • Ranged weapons ammo will be automatically replenished over time.
  • Added Ranged Mastery (Bows/Crossbows/ThrowingKnives/ThrowingAxes)
    • ‘Ranged Kills’ will be increased by killing enemies with ranged weapons.
    • Ranged weapons have {Its Original Damage + (0.3 * ‘Ranged Kills’)}.
    • Replenishment rate of ranged weapons ammo will be slightly faster depends on ‘Ranged Kills’.
    • Shooting/Throwing process will be slightly shortened depends on ‘Ranged Kills’.
    • Killing with ranged weapons will heal the players with above certain amount of ‘Ranged Kills’. (5HP with 50 >= ‘Ranged Kills’, 10HP with 100>= ‘Ranged Kills’)
    • Dealing damage with ranged weapons will heal the players with above certain amount of ‘Ranged Kills’. (5HP with 200 >= ‘Ranged Kills’)
  • New Small Maps (Melee Weapons from Random Chests Only)
    • Contraband
    • The Pit
    • Tourney
  • Purchasable Perks (Lesser Bloodlust, Rush, Fury, Dodge, Unflinchable, Tank)
    • Lesser Bloodlust : Increases heal amount upon killing an enemy with melee weapons.
    • Rush : Movement will be faster and Instantly begin sprinting upon killing an enemy.
    • Fury : Fully restores stamina on kill.
    • Dodge : Jumping while moving backwards or sideways will perform a quick dodging motion rather than a regular jump.
    • Unflinchable : Attacks won’t be canceled by getting hit.
    • Tank : Increases player’s size little bit, reduces damage taken from melee and ranged weapons.
  • Superior(○)/Rare(●) Weapons are added to random chests.
    • Superior(○) Weapons : Deals 30% more damage done. Additionally appends bonus damage depends on original weapon damage.
    • Rare(●) Weapons : Deals 80% more damage done. Added 30% chip damage on blocked is added on attack. Additionally appends bonus damage depends on original weapon damage.
  • Nightmare/Hell difficulties beyond 21th wave. (22-28/29-31)
    • Nightmare difficulty : Total 7 waves. Each wave is a summary of 3 waves from Normal difficulty. Minions carry Superior(○) weapons. All enemies will take less damage from players.
    • Hell difficulty : Total 3 waves. Each wave is a summary of 7 waves from Normal difficulty. Bosses & Minions carry Rare(●) weapons. All enemies will take much less damage from players.

Weapons

NormalSuperior(ㅇ)Rare(●)Unique(◎)
Rusty Arming SwordAncient Arming SwordDaedric Shortsword
Broken Arming SwordBroken Ancient Arming SwordSeven-Branched Sword Hilt
Rusty LongswordAncient LongswordDaedric Longsword
Broken LongswordBroken Ancient LongswordNarsil
Carving KnifeButter KnifeMihawk’s NecklaceSumerian Butter Knife
Frying PanChef’s PanHoradric Pan
Training SwordCoaching SwordDimensional SwordSumerian Sword
PitchforkEnt HandEarth Shaker
Wooden ShovelEnt SpoonValhalla Oar
Rusty ShovelBlade ShovelEfficiency V Shovel
Heavy BranchCudgelMoon Tenderizer
PickaxeCrowbillPompeii’s Wrath
ScytheGrim ScytheSoul Harvest
SickleHomiDaedric Crescent
HoeMattockSkull Splitter
Rusty ForkStygian PikeFork of Horripilation
RakeWooden SpikesEarth Shifter
Wooden MalletWoodenstoneImperial Legion Seal
SledgehammerBonesnapThe Cranium Basher
Short SwordRondelSpectral Shard
DaggerPoignardKeening
Arming SwordGladiusDjinn Falcata
Executioner’s SwordChamsu BladeSwordguardGuillotine Sword
PolehammerBec De CorbinHusoldal Evo
GreatswordEspandonSoul Flayer
ZweihanderFlambergeThe Grandfather
PartisanFuscinaRazortine
BillhookGlaiveBill
Bastard SwordGothic SwordUmbra
Pole AxeGreat Pole AxeTrulla Apocalypsi
Heavy HandaxeHand Pole AxeLegendary War Mallet
AxeHatchetTomahawk
EveningstarHeavy AspergillumCaduceusNoonstar
Blacksmith HammerIronstoneSunder
RapierKrisSpada da lato
BardicheLochaber AxeNerveshatter
LongswordRune SwordHonorblade of Chorrol
MesserMangnani BladeMagebane
MaulMartel de FerGavel of PainGreat Maul
MaceMorning StarMoonfall
War AxeNagaThe Chieftain
EstocOakeshott Types XVKoncerz
LuteOudGalápagos LyreAtavachron
SpearPikeMancatcher
WarhammerPineapple ClubSeraph Rod
FalxSicaRhomphaiaBloodthirst Falx
Short SpearSimbilanHarpoon
CleaverSmall CrescentGull
QuarterstaffStalagmiteOndal’s WisdomGandalf Staff
HalberdSteelgoadWoestave
Battle AxeTabarPierre Tombale CouantRhythm Axe
FalchionTulwarAli Baba BladeDwarf Galaxy
ClubWar ClubGnomestickOgre Club
CarrotRadishAncient Red GinsengSumerian Carrot
Beer JugKrügeDas Boot
StoolLoungeYggdrasil
LongbowSumerian Bow

How to install ZeroTier-One VPN on OpenBSD

※ In this article, I have used OpenBSD 7.2 and ZeroTier One 1.10.6.
The most current versions for the OS and software at the time of writing.

OS Information

$ uname -a

OpenBSD openbsd.ourdare.com 7.2 GENERIC.MP#758 amd64

Install Requirements

$ sudo pkg_add wget gmake

quirks-6.42 signed on 2023-03-21T19:29:38Z
wget-1.21.3:libunistring-0.9.7: ok
wget-1.21.3:libidn2-2.3.0p0: ok
wget-1.21.3:bzip2-1.0.8p0: ok
wget-1.21.3:pcre2-10.37: ok
wget-1.21.3:libpsl-0.21.1: ok
wget-1.21.3: ok
gmake-4.3: ok

Download and Extract ZeroTier-One Source

$ wget https://github.com/zerotier/ZeroTierOne/archive/refs/tags/1.10.6.tar.gz

--2023-03-29 14:05:54--  https://github.com/zerotier/ZeroTierOne/archive/refs/tags/1.10.6.tar.gz
github.com (github.com) 해석 중... 20.200.245.247
다음으로 연결 중: github.com (github.com)|20.200.245.247|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 302 Found
위치: https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/refs/tags/1.10.6 [따라감]
--2023-03-29 14:05:55--  https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/refs/tags/1.10.6
codeload.github.com (codeload.github.com) 해석 중... 20.200.245.246
다음으로 연결 중: codeload.github.com (codeload.github.com)|20.200.245.246|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 200 OK
길이: 15259391 (15M) [application/x-gzip]
저장 위치: `1.10.6.tar.gz'

1.10.6.tar.gz	100%[======================================================================>]  14.55M  6.90MB/s    /  2.1s

2023-03-29 14:05:57 (6.90 MB/s) - `1.10.6.tar.gz' 저장함 [15259391/15259391]



$ tar xzf 1.10.6.tar.gz

Build & Install

$ cd ZeroTierOne-1.10.6



$ gmake && sudo gmake install

Register a Service

Open a new file /etc/rc.d/zerotier with an editor and fill it with the contents below and then save.

#!/bin/ksh

daemon="/usr/local/sbin/zerotier-one -d"

. /etc/rc.d/rc.subr

rc_cmd $1
$ sudo chmod u+x /etc/rc.d/zerotier



$ sudo rcctl enable zerotier



$ sudo rcctl start zerotier

zerotier(ok)

Use Commands

$ sudo zerotier-cli info
200 info ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ 1.10.6 ONLINE



$ sudo zerotier-cli join <networkid>

How to build an OpenTTD JGRPP Dedicated Server on OmniOS (Unix / Oracle Solaris / illumos)

※ In this article, I have used OmniOS r151038 and JGRPP v0.52.0.
At the moment, r151038 is the latest LTS OmniOS release and JGRPP v0.52.0 is the latest version release.

OS Information

~$ uname -a



SunOS omnioslts 5.11 omnios-r151038-7bb369b3b5 i86pc i386 i86pc



~$ cat /etc/os-release



NAME="OmniOS"
PRETTY_NAME="OmniOS Community Edition v11 r151038cs"
CPE_NAME="cpe:/o:omniosce:omnios:11:151038:97"
ID=omnios
VERSION=r151038cs
VERSION_ID=r151038cs
BUILD_ID=151038.97.2023.03.11
HOME_URL="https://omnios.org/"
SUPPORT_URL="https://omnios.org/"
BUG_REPORT_URL="https://github.com/omniosorg/omnios-build/issues/new"

Install Requirements

~$ sudo pkg install gcc10 cmake gnu-make



설치할 패키지:   2
변경할 서비스:   1
부트 환경 만들기: 아니오
백업 부트 환경 만들기: 아니오

다운로드		패키지	파일		XFER(MB)		속도
완료됨		2/2	3199/3199	25.5/25.5		471k/s

단계					항목
작업 설치				3358/3358
패키지 상태 데이터베이스 업데이트		완료
패키지 캐시 업데이트			0/0
이미지 상태 업데이트			완료
빠른 조회 데이터베이스 만들기		완료
검색 색인 읽기				완료
검색 색인 업데이트			2/2
패키지 캐시 업데이트			2/2



~$ gcc --version



gcc (OmniOS 151038/10.4.0-il-1) 10.4.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



~$ cmake --version



cmake version 3.25.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).



~$ gmake --version



GNU Make 4.3
Built for x86_64-pc-solaris2.11
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Download and Extract JGRPP Source

~$ wget https://github.com/JGRennison/OpenTTD-patches/archive/refs/tags/jgrpp-0.52.0.tar.gz



--2023-03-24 15:02:55--  https://github.com/JGRennison/OpenTTD-patches/archive/refs/tags/jgrpp-0.52.0.tar.gz
Resolving github.com... 20.200.245.247
Connecting to github.com|20.200.245.247|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/JGRennison/OpenTTD-patches/tar.gz/refs/tags/jgrpp-0.52.0 [following]
--2023-03-24 15:02:56--  https://codeload.github.com/JGRennison/OpenTTD-patches/tar.gz/refs/tags/jgrpp-0.52.0
Resolving codeload.github.com... 20.200.245.246
Connecting to codeload.github.com|20.200.245.246|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: ‘jgrpp-0.52.0.tar.gz’

jgrpp-0.52.0.tar.gz                      [          <=>                                                         ]  11.64M  6.13MB/s    in 1.9s

2023-03-24 15:02:58 (6.13 MB/s) - ‘jgrpp-0.52.0.tar.gz’ saved [12207921]



~$ tar xzf jgrpp-0.52.0.tar.gz

Modify Source Files

Go to the source folder root.

~$ cd OpenTTD-patches-jgrpp-0.52.0

Open CMakeLists.txt with an editor and add 3 lines in target_link_libraries function located at line 313 and it should look like below.

${CMAKE_DL_LIBS}
-lsocket
-lnsl


add_dependencies(openttd
    find_version)

target_link_libraries(openttd
    openttd::languages
    openttd::settings
    openttd::media
    openttd::basesets
    openttd::script_api
    openttd::binfiles
    Threads::Threads
    ${CMAKE_DL_LIBS}
    -lsocket
    -lnsl
)

if(HAIKU)
    target_link_libraries(openttd "be" "network" "midi")
endif()

Open build-dedicated.sh with an editor and replace make at line 7 with gmake and it should look like below.


cd build
rm CMakeCache.txt
cmake .. -DOPTION_DEDICATED=true && gmake -j$(nproc 2>/dev/null || echo "1")

Open src/core/alloc_func.hpp with an editor and add 3 lines at the beginning and it should look like below.

#ifdef __sun
#include <alloca.h>
#endif
#ifdef __sun
#include <alloca.h>
#endif

/*
 * This file is part of OpenTTD.

Open src/string_func.h comment out the line at line 279 and it should look like below.



#       define DEFINE_STRCASESTR
// char *strcasestr(const char *haystack, const char *needle);
#endif /* strcasestr is available */

Open src/network/core/os_abstraction.cpp with an editor and replace SO_REUSEPORT at line 196 with SO_REUSEADDR and it should look like below.



#else
        int reuse_port = 1;
        return setsockopt(d, SOL_SOCKET, SO_REUSEADDR, &reuse_port, sizeof(reuse_port)) == 0;
#endif
}

Open src/3rdparty/randombytes/randombytes.h with an editor and replace a function randombytes line at line 19 and it should look like below.



/*
 * Write `n` bytes of high quality random bytes to `buf`
 */
int randombytes(unsigned char *buf, size_t n);

#ifdef __cplusplus
}
#endif

Open src/3rdparty/randombytes/randombytes.c with an editor and delete all contents and then fill with below.

#include "randombytes.h"
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

int randombytes(unsigned char *x, size_t xlen)
{
    int fd;
    ssize_t bytes_read;

    if (xlen == 0) return 0;
    assert(x != NULL);

    fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1) {
        fd = open("/dev/random", O_RDONLY);
    }
    assert(fd != -1);

    bytes_read = read(fd, x, xlen);
    assert(bytes_read == xlen);

    close(fd);

    return 0;
}

Open src/os/unix/crashlog_unix.cpp with an editor and add a line #include <ucontext.h> right after #include <sys/mman.h> at line 25 and it should look like below.


#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <ucontext.h>

#if defined(WITH_DBG_GDB)
#include <sys/syscall.h>
#endif /* WITH_DBG_GDB */

And in the same file, replace two gregs[REG_EFL] at line 400, 418 with gregs[REG_RFL] and it should look like below.


                        gregs[REG_R14],
                        gregs[REG_R15],
                        gregs[REG_RIP],
                        gregs[REG_RFL]
                );
#elif defined(__i386)
                const gregset_t &gregs = ucontext->uc_mcontext.gregs;
                buffer += seprintf(buffer, last,

                        gregs[REG_EBP],
                        gregs[REG_ESP],
                        gregs[REG_EIP],
                        gregs[REG_RFL]
                );
#endif
#endif

Build

~$ ./build-dedicated.sh

Download and extract Base Graphics

~$ wget https://cdn.openttd.org/opengfx-releases/7.1/opengfx-7.1-all.zip



Resolving cdn.openttd.org... 54.230.167.118, 54.230.167.93, 54.230.167.82, ...
Connecting to cdn.openttd.org|54.230.167.118|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3547160 (3.4M) [application/zip]
Saving to: ‘opengfx-7.1-all.zip’

opengfx-7.1-all.zip                  100%[=====================================================================>]   3.38M  9.53MB/s    in 0.4s

2023-03-24 16:02:24 (9.53 MB/s) - ‘opengfx-7.1-all.zip’ saved [3547160/3547160]



~$ unzip opengfx-7.1-all.zip && mv opengfx-7.1.tar build/baseset/



Archive:  opengfx-7.1-all.zip
  inflating: opengfx-7.1.tar

Install

~$ cd build && sudo gmake install

Launch the dedicated server

~$ /usr/local/games/openttd -D