<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>blog.raizo.dev</title><subtitle>Technical notes on systems programming, backend development and other.</subtitle><link rel="self" type="application/atom+xml" href="https://blog.raizo.dev/atom.xml"/><link rel="alternate" type="text/html" href="https://blog.raizo.dev"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2021-01-05T00:00:00+00:00</updated><id>https://blog.raizo.dev/atom.xml</id><entry xml:lang="en"><title>TF2 Classic SourceMod+Metamod Setup</title><published>2021-01-05T00:00:00+00:00</published><updated>2021-01-05T00:00:00+00:00</updated><author><name>
Unknown</name></author><link rel="alternate" type="text/html" href="https://blog.raizo.dev/posts/tf2-classic-sourcemod-setup/"/><id>https://blog.raizo.dev/posts/tf2-classic-sourcemod-setup/</id><content type="html" xml:base="https://blog.raizo.dev/posts/tf2-classic-sourcemod-setup/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you do not have a TF2 Classic server running yet, use &lt;a rel="noopener external" target="_blank" href="https://iraizo.github.io/tf2-classic-linux-server-tutorial/"&gt;this dedicated server guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;SourceMod on TF2 Classic is not fully drag-and-drop like official SourceMod games (for example TF2 and CS:Source). TF2 Classic is a Source SDK 2013 mod, so game name (&lt;code&gt;tf2classic&lt;/code&gt;), signatures, and offsets are different.&lt;/p&gt;
&lt;p&gt;The information in Discord pins is scattered and sometimes outdated. This post is a single walkthrough for the full setup process.&lt;/p&gt;
&lt;h2 id="1-download-sourcemod-and-metamod"&gt;&lt;a class="zola-anchor" href="#1-download-sourcemod-and-metamod" aria-label="Anchor link for: 1-download-sourcemod-and-metamod"&gt;1. Download SourceMod and MetaMod&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Go to &lt;a rel="noopener external" target="_blank" href="https://www.sourcemod.net/downloads.php?branch=stable"&gt;SourceMod stable builds&lt;/a&gt; and get the latest Linux build.&lt;/p&gt;
&lt;p&gt;Download it directly to the server:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;curl&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;L&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;O&lt;/span&gt;&lt;span class="z-string"&gt; https://sm.alliedmods.net/smdrop/1.10/sourcemod-1.10.0-git6502-linux.tar.gz&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-punctuation z-definition z-comment"&gt;#&lt;/span&gt;&lt;span class="z-comment"&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;wget&lt;/span&gt;&lt;span class="z-string"&gt; https://sm.alliedmods.net/smdrop/1.10/sourcemod-1.10.0-git6502-linux.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; This archive URL can go out of date. Get the newest direct download URL yourself and replace it as needed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You also need a stable Linux build of Metamod:Source from &lt;a rel="noopener external" target="_blank" href="https://www.sourcemm.net/downloads.php?branch=stable"&gt;sourcemm.net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Place both archives in your &lt;code&gt;tf2classic&lt;/code&gt; game folder:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;location_of_sdk2013ds/tf2classic&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Extract both archives there:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;tar&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;xf&lt;/span&gt;&lt;span class="z-string"&gt; sourcemod-1.10.0-git6502-linux.tar.gz&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;tar&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;xf&lt;/span&gt;&lt;span class="z-string"&gt; mmsource-1.11.0-git1144-linux.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Feel free to remove the archives.&lt;/p&gt;
&lt;h2 id="2-replace-metamod-vdf"&gt;&lt;a class="zola-anchor" href="#2-replace-metamod-vdf" aria-label="Anchor link for: 2-replace-metamod-vdf"&gt;2. Replace &lt;code&gt;metamod.vdf&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After extraction, you should have an &lt;code&gt;addons&lt;/code&gt; folder:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-sourcemod-setup/addons-after-extract.png" alt="Addons folder after extracting SM and MM" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;metamod.vdf&lt;/code&gt; is required for game detection. Since TF2 Classic is a mod, create one that points to &lt;code&gt;tf2classic&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Delete the existing &lt;code&gt;addons/metamod.vdf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open &lt;a rel="noopener external" target="_blank" href="https://www.sourcemm.net/vdf"&gt;sourcemm.net/vdf&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Leave &lt;code&gt;Game&lt;/code&gt; blank (or &lt;code&gt;---&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;Game Folder&lt;/code&gt; to &lt;code&gt;tf2classic&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It should look like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-sourcemod-setup/metamod-generator-example.png" alt="Metamod generator page example" /&gt;&lt;/p&gt;
&lt;p&gt;Download the generated file, upload it to your server, and place it in &lt;code&gt;addons&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-sourcemod-setup/addons-after-new-metamod-vdf.png" alt="Addons folder after adding the new metamod.vdf" /&gt;&lt;/p&gt;
&lt;h2 id="3-import-custom-gamedata"&gt;&lt;a class="zola-anchor" href="#3-import-custom-gamedata" aria-label="Anchor link for: 3-import-custom-gamedata"&gt;3. Import custom gamedata&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To make features like showmenu, radio menu, and HUD messages work, import custom gamedata.&lt;/p&gt;
&lt;p&gt;Do not edit &lt;code&gt;common.games.txt&lt;/code&gt; anymore. That approach is unreliable and can require disabling auto-updates. Use &lt;code&gt;custom&lt;/code&gt; subdirectories instead.&lt;/p&gt;
&lt;p&gt;If your server has &lt;code&gt;git&lt;/code&gt;, go to your &lt;code&gt;tf2classic&lt;/code&gt; directory and clone:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;git&lt;/span&gt;&lt;span class="z-string"&gt; clone&lt;/span&gt;&lt;span class="z-string"&gt; https://github.com/Scags/TF2Classic-Tools.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you do not have &lt;code&gt;git&lt;/code&gt;, download the repo archive:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;wget&lt;/span&gt;&lt;span class="z-string"&gt; https://github.com/Scags/TF2Classic-Tools/archive/master.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-punctuation z-definition z-comment"&gt;#&lt;/span&gt;&lt;span class="z-comment"&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;curl&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;L&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;O&lt;/span&gt;&lt;span class="z-string"&gt; https://github.com/Scags/TF2Classic-Tools/archive/master.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-punctuation z-definition z-comment"&gt;#&lt;/span&gt;&lt;span class="z-comment"&gt; then unzip it&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;unzip&lt;/span&gt;&lt;span class="z-string"&gt; master.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-punctuation z-definition z-comment"&gt;#&lt;/span&gt;&lt;span class="z-comment"&gt; if you do not have unzip, install it using: sudo apt install unzip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then &lt;code&gt;cd&lt;/code&gt; into either &lt;code&gt;TF2Classic-Tools&lt;/code&gt; or &lt;code&gt;TF2Classic-Tools-master&lt;/code&gt; (depends on download method).&lt;/p&gt;
&lt;p&gt;Copy the &lt;code&gt;sourcemod&lt;/code&gt; directory into your &lt;code&gt;addons&lt;/code&gt; folder:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;cp&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;r&lt;/span&gt;&lt;span class="z-string"&gt; sourcemod/&lt;/span&gt;&lt;span class="z-string"&gt; ../addons/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now SourceMod and MetaMod should have the TF2C gamedata they need.&lt;/p&gt;
&lt;h2 id="4-set-yourself-as-the-root-admin-user"&gt;&lt;a class="zola-anchor" href="#4-set-yourself-as-the-root-admin-user" aria-label="Anchor link for: 4-set-yourself-as-the-root-admin-user"&gt;4. Set yourself as the "root" admin user&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To use admin commands, add your Steam ID to SourceMod's admin config.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Find your Steam ID using &lt;a rel="noopener external" target="_blank" href="https://steamid.io"&gt;steamid.io&lt;/a&gt; (enter custom URL or SteamID64 and copy the &lt;code&gt;steamID&lt;/code&gt; line).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-sourcemod-setup/steamid-example.png" alt="Example Steam lookup" /&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Open &lt;code&gt;tf2classic/addons/sourcemod/configs/admins_simple.ini&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add this line at the bottom:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="plain"&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;&amp;quot;steamID&amp;quot; &amp;quot;99:z&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;99:z&lt;/code&gt; means &lt;em&gt;all&lt;/em&gt; permissions. Only grant this to trusted server operators.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-sourcemod-setup/admins-simple-example.png" alt="Example admins_simple.ini" /&gt;&lt;/p&gt;
&lt;p&gt;For reduced permissions, use the comments in that file plus the AlliedModders wiki:
&lt;a rel="noopener external" target="_blank" href="https://wiki.alliedmods.net/Adding_Admins_(SourceMod)"&gt;Adding Admins (SourceMod)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Save the file, then start your server up and have fun!&lt;/p&gt;
&lt;h2 id="5-troubleshooting"&gt;&lt;a class="zola-anchor" href="#5-troubleshooting" aria-label="Anchor link for: 5-troubleshooting"&gt;5. Troubleshooting&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="map-voting-note"&gt;&lt;a class="zola-anchor" href="#map-voting-note" aria-label="Anchor link for: map-voting-note"&gt;Map voting note&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You should not need to delete &lt;code&gt;nextmap.smx&lt;/code&gt;.
If map voting fails, try disabling/removing that plugin and test again. There are other map voting plugins available.&lt;/p&gt;
&lt;h3 id="missing-dhooks-ext"&gt;&lt;a class="zola-anchor" href="#missing-dhooks-ext" aria-label="Anchor link for: missing-dhooks-ext"&gt;Missing &lt;code&gt;dhooks.ext&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You might see an error about missing &lt;code&gt;dhooks.ext&lt;/code&gt;.
It is usually safe to ignore &lt;strong&gt;if no installed plugin depends on DHooks&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you use something like Scags' TF2C Crash Exploit Fixes, install DHooks with Detours:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel="noopener external" target="_blank" href="https://forums.alliedmods.net/attachment.php?attachmentid=184479&amp;amp;d=1602926778"&gt;DHooks with Detours (SourceMod v1.10+)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="noopener external" target="_blank" href="https://forums.alliedmods.net/attachment.php?attachmentid=184480&amp;amp;d=1602926778"&gt;DHooks with Detours (pre-SourceMod v1.10)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Original post:
&lt;a rel="noopener external" target="_blank" href="https://forums.alliedmods.net/showpost.php?p=2588686&amp;amp;postcount=589"&gt;AlliedModders forum post&lt;/a&gt;&lt;/p&gt;</content></entry><entry xml:lang="en"><title>TF2 Classic Ubuntu Linux Dedicated Server Guide</title><published>2020-07-05T00:00:00+00:00</published><updated>2020-07-05T00:00:00+00:00</updated><author><name>
Unknown</name></author><link rel="alternate" type="text/html" href="https://blog.raizo.dev/posts/tf2-classic-ubuntu-linux-dedicated-server-guide/"/><id>https://blog.raizo.dev/posts/tf2-classic-ubuntu-linux-dedicated-server-guide/</id><content type="html" xml:base="https://blog.raizo.dev/posts/tf2-classic-ubuntu-linux-dedicated-server-guide/">&lt;h2 id="prerequisites"&gt;&lt;a class="zola-anchor" href="#prerequisites" aria-label="Anchor link for: prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Linux server running Ubuntu Server* on an x86_64 CPU. SRCDS will not run on other architectures (sorry Raspberry Pi folks).&lt;/li&gt;
&lt;li&gt;A SFTP/SSH client (PuTTY, Termius, FileZilla, MobaXterm, etc.)&lt;/li&gt;
&lt;li&gt;At least 16GB free storage&lt;/li&gt;
&lt;li&gt;At least 10Mbps upload if you want players to join over the Internet (LAN-only servers do not care as much)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This guide was written and tested on Ubuntu Server 20.04 LTS, but most Debian-based distros should be very similar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;*Ubuntu 20.04 LTS is where Canonical started phasing out many i386 libraries from main repos. TF2C/Steam/SteamCMD are known to work, but some Source games, plugins, or addons can still need extra package sources.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="1-create-a-steam-user"&gt;&lt;a class="zola-anchor" href="#1-create-a-steam-user" aria-label="Anchor link for: 1-create-a-steam-user"&gt;1. Create a &lt;code&gt;steam&lt;/code&gt; user&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pick an install location first:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/opt&lt;/code&gt; is the usual server location&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/home&lt;/code&gt; is also fine if you prefer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you install in &lt;code&gt;/home&lt;/code&gt;, you can omit &lt;code&gt;-d&lt;/code&gt; and let &lt;code&gt;useradd&lt;/code&gt; create the home directory automatically.&lt;/p&gt;
&lt;p&gt;For this guide, we will use &lt;code&gt;/opt/tf2classic&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; useradd&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;m&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;d&lt;/span&gt;&lt;span class="z-string"&gt; /opt/tf2classic&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; /usr/bin/bash&lt;/span&gt;&lt;span class="z-string"&gt; steam&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; passwd&lt;/span&gt;&lt;span class="z-string"&gt; steam&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-m&lt;/code&gt; creates the home directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d /opt/tf2classic&lt;/code&gt; sets it explicitly&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s /usr/bin/bash&lt;/code&gt; sets the shell&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-install-dependencies-and-source-sdk-base-2013-ds"&gt;&lt;a class="zola-anchor" href="#2-install-dependencies-and-source-sdk-base-2013-ds" aria-label="Anchor link for: 2-install-dependencies-and-source-sdk-base-2013-ds"&gt;2. Install dependencies and Source SDK Base 2013 DS&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SteamCMD is in the multiverse repo. TF2C and SteamCMD also require i386 libraries. You will also need &lt;code&gt;p7zip-full&lt;/code&gt; for TF2 Classic archives.&lt;/p&gt;
&lt;p&gt;Enable repos/architecture and refresh package metadata:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; add-apt-repository&lt;/span&gt;&lt;span class="z-string"&gt; multiverse&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; dpkg&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;-add-architecture&lt;/span&gt;&lt;span class="z-string"&gt; i386&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; apt&lt;/span&gt;&lt;span class="z-string"&gt; update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install required packages:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; apt&lt;/span&gt;&lt;span class="z-string"&gt; install&lt;/span&gt;&lt;span class="z-string"&gt; steamcmd&lt;/span&gt;&lt;span class="z-string"&gt; p7zip-full&lt;/span&gt;&lt;span class="z-string"&gt; unzip&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; apt&lt;/span&gt;&lt;span class="z-string"&gt; install&lt;/span&gt;&lt;span class="z-string"&gt; libncurses5:i386&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Switch to the &lt;code&gt;steam&lt;/code&gt; user and launch SteamCMD:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;su&lt;/span&gt;&lt;span class="z-string"&gt; -&lt;/span&gt;&lt;span class="z-string"&gt; steam&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;steamcmd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run these commands inside SteamCMD:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="plain"&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;login anonymous&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;force_install_dir /opt/tf2classic/server&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;app_update 244310 validate&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="3-download-and-extract-tf2-classic"&gt;&lt;a class="zola-anchor" href="#3-download-and-extract-tf2-classic" aria-label="Anchor link for: 3-download-and-extract-tf2-classic"&gt;3. Download and extract TF2 Classic&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Download the full game archive (&lt;strong&gt;not&lt;/strong&gt; a patch) from one of these mirrors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel="noopener external" target="_blank" href="https://khromier.com/tf2c/tf2classic-2.0.1.7z"&gt;https://khromier.com/tf2c/tf2classic-2.0.1.7z&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="noopener external" target="_blank" href="https://gg.apple-shack.org/tf2c/tf2classic-latest.7z"&gt;https://gg.apple-shack.org/tf2c/tf2classic-latest.7z&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Expected MD5 checksums:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="plain"&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;A2F240E0136B0E330C91D788CD317AFC *tf2classic-2.0.1.7z&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;CB9C8F8F732FBF118C1149F8D2A07DAB *tf2classic-latest.7z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Archive sizes may differ due to compression, but extracted data should match.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-ubuntu-linux-dedicated-server-guide/sha256-checksums-post-extraction.png" alt="SHA256 checksums for both folders post-extraction." /&gt;&lt;/p&gt;
&lt;p&gt;Download on the server:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;wget&lt;/span&gt;&lt;span class="z-string"&gt; https://khromier.com/tf2c/tf2classic-2.0.1.7z&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-punctuation z-definition z-comment"&gt;#&lt;/span&gt;&lt;span class="z-comment"&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;curl&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;L&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;O&lt;/span&gt;&lt;span class="z-string"&gt; https://khromier.com/tf2c/tf2classic-2.0.1.7z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If your connection is unstable, grab the torrent on another machine, then upload via SFTP:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;magnet:?xt=urn:btih:2fc7113011ff80f8f05ad8df00b8228aad230117&amp;amp;dn=tf2classic-2.0.1.7z&amp;amp;tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Extract and move the folder into your SDK directory:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;7z&lt;/span&gt;&lt;span class="z-string"&gt; x&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic-2.0.1.7z&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;mv&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic&lt;/span&gt;&lt;span class="z-string"&gt; insert_full_path_to_server_directory_here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="4-configure-server-files"&gt;&lt;a class="zola-anchor" href="#4-configure-server-files" aria-label="Anchor link for: 4-configure-server-files"&gt;4. Configure server files&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Generate config files on &lt;a rel="noopener external" target="_blank" href="https://cfg.tf/server/"&gt;cfg.tf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Set server type to &lt;strong&gt;Internet and LAN&lt;/strong&gt; if people outside your LAN should join.&lt;/p&gt;
&lt;p&gt;Upload the generated ZIP via SFTP, then:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;unzip&lt;/span&gt;&lt;span class="z-keyword"&gt; &amp;lt;&lt;/span&gt;&lt;span class="z-string"&gt;archiv&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span class="z-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="z-string"&gt;.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;mv&lt;/span&gt;&lt;span class="z-string"&gt; cfg&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic/cfg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="5-create-the-launch-script"&gt;&lt;a class="zola-anchor" href="#5-create-the-launch-script" aria-label="Anchor link for: 5-create-the-launch-script"&gt;5. Create the launch script&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All commands in this section are run in the server directory where &lt;code&gt;srcds_run&lt;/code&gt; exists.&lt;/p&gt;
&lt;p&gt;Create &lt;code&gt;runserver.sh&lt;/code&gt; with your editor:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;nano&lt;/span&gt;&lt;span class="z-string"&gt; runserver.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Put this in it:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;./srcds_run&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;console&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;game&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic&lt;/span&gt;&lt;span class="z-string"&gt; +map&lt;/span&gt;&lt;span class="z-string"&gt; pl_upward&lt;/span&gt;&lt;span class="z-string"&gt; +maxplayers&lt;/span&gt;&lt;span class="z-constant"&gt; 24&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Feel free to change map/player count.&lt;/p&gt;
&lt;p&gt;Save it, then make it executable:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;chmod&lt;/span&gt;&lt;span class="z-string"&gt; +x&lt;/span&gt;&lt;span class="z-string"&gt; runserver.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="6-required-symlink-fix"&gt;&lt;a class="zola-anchor" href="#6-required-symlink-fix" aria-label="Anchor link for: 6-required-symlink-fix"&gt;6. Required symlink fix&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Valve renamed several SDK shared object files, while TF2C still expects older names.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your server will not start without these symlinks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Go to your SDK &lt;code&gt;bin&lt;/code&gt; directory:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-support"&gt;cd&lt;/span&gt;&lt;span class="z-string"&gt; bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;This is &lt;code&gt;bin&lt;/code&gt; inside your server install, &lt;strong&gt;not&lt;/strong&gt; &lt;code&gt;/bin&lt;/code&gt; from the root filesystem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Create symlinks:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; datacache_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; datacache.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; dedicated_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; dedicated.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; engine_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; engine.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; materialsystem_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; materialsystem.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; replay_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; replay.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; scenefilecache_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; scenefilecache.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; shaderapiempty_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; shaderapiempty.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; studiorender_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; studiorender.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; vphysics_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; vphysics.so&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;ln&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;s&lt;/span&gt;&lt;span class="z-string"&gt; soundemittersystem_srv.so&lt;/span&gt;&lt;span class="z-string"&gt; soundemittersystem.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterward, your &lt;code&gt;bin&lt;/code&gt; directory should look similar to this:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/posts/tf2-classic-ubuntu-linux-dedicated-server-guide/bin-folder-after-symlinks.png" alt="bin folder after symlinks" /&gt;&lt;/p&gt;
&lt;h2 id="7-run-the-server"&gt;&lt;a class="zola-anchor" href="#7-run-the-server" aria-label="Anchor link for: 7-run-the-server"&gt;7. Run the server&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start it with:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;./runserver.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="faq"&gt;&lt;a class="zola-anchor" href="#faq" aria-label="Anchor link for: faq"&gt;FAQ&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="libncurses5-warning-still-appears"&gt;&lt;a class="zola-anchor" href="#libncurses5-warning-still-appears" aria-label="Anchor link for: libncurses5-warning-still-appears"&gt;&lt;code&gt;libncurses5&lt;/code&gt; warning still appears&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="plain"&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;WARNING: Failed to load 32-bit libtinfo.so.5 or libncurses.so.5.&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;Please install (lib32tinfo5 / ncurses-libs.i686 / equivalent) to enable readline&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the i386 package variant:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; apt&lt;/span&gt;&lt;span class="z-string"&gt; install&lt;/span&gt;&lt;span class="z-string"&gt; libncurses5:i386&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You probably installed only the amd64 package before.&lt;/p&gt;
&lt;h3 id="no-installation-candidate-for-steamcmd"&gt;&lt;a class="zola-anchor" href="#no-installation-candidate-for-steamcmd" aria-label="Anchor link for: no-installation-candidate-for-steamcmd"&gt;No installation candidate for &lt;code&gt;steamcmd&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Enable multiverse + i386 architecture and update package metadata:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; add-apt-repository&lt;/span&gt;&lt;span class="z-string"&gt; multiverse&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; dpkg&lt;/span&gt;&lt;span class="z-constant"&gt; -&lt;/span&gt;&lt;span class="z-constant"&gt;-add-architecture&lt;/span&gt;&lt;span class="z-string"&gt; i386&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; apt&lt;/span&gt;&lt;span class="z-string"&gt; update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="other-users-can-t-connect-to-my-server"&gt;&lt;a class="zola-anchor" href="#other-users-can-t-connect-to-my-server" aria-label="Anchor link for: other-users-can-t-connect-to-my-server"&gt;Other users can't connect to my server&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Two common reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Consumer broadband often needs UDP port forwarding (&lt;code&gt;27015&lt;/code&gt;) on your router.&lt;/li&gt;
&lt;li&gt;VPS firewalls may block traffic by default.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are on consumer broadband and not sure how to port forward, search for:
&lt;code&gt;how to port forward on &amp;lt;your router model&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For UFW:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; ufw&lt;/span&gt;&lt;span class="z-string"&gt; allow&lt;/span&gt;&lt;span class="z-string"&gt; 27015/udp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use RCON (for example SourceBans), you also need a TCP RCON port (often &lt;code&gt;27015/tcp&lt;/code&gt;) and the appropriate launch args.&lt;/p&gt;
&lt;p&gt;Also make sure players connect to your &lt;strong&gt;WAN&lt;/strong&gt; IP, not your LAN IP:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;curl&lt;/span&gt;&lt;span class="z-string"&gt; ifconfig.me&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example in game console:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="plain"&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;connect 42.0.13.337&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test exposed ports from another machine on your network, use &lt;a rel="noopener external" target="_blank" href="https://canyouseeme.org"&gt;canyouseeme.org&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="installing-sourcemod-for-tf2-classic"&gt;&lt;a class="zola-anchor" href="#installing-sourcemod-for-tf2-classic" aria-label="Anchor link for: installing-sourcemod-for-tf2-classic"&gt;Installing SourceMod for TF2 Classic&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;TF2C SourceMod/MetaMod setup is not plug-and-play like stock TF2/CSS. Use the dedicated guide here:&lt;/p&gt;
&lt;p&gt;&lt;a href="/posts/tf2-classic-sourcemod-setup/"&gt;TF2 Classic SourceMod+MetaMod Setup&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="optional-systemd-autostart"&gt;&lt;a class="zola-anchor" href="#optional-systemd-autostart" aria-label="Anchor link for: optional-systemd-autostart"&gt;Optional: systemd autostart&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is a very basic unit file to get automatic startup on reboot. It works, but it is limited and not the most robust production setup.&lt;/p&gt;
&lt;p&gt;I still do not recommend this for long-term production use. You cannot attach to the server console directly with this layout, and restart behavior is very basic.&lt;/p&gt;
&lt;p&gt;Create &lt;code&gt;tf2classic.service&lt;/code&gt; as root (or an elevated user) in:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/usr/lib/systemd/system/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Use:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="ini"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;[&lt;/span&gt;&lt;span class="z-entity z-name"&gt;Unit&lt;/span&gt;&lt;span class="z-entity z-name"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;Description&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;Team Fortress 2 Classic Server&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;RefuseManualStart&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;no&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;RefuseManualStop&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;yes&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;After&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;network.target&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;[&lt;/span&gt;&lt;span class="z-entity z-name"&gt;Service&lt;/span&gt;&lt;span class="z-entity z-name"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;User&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;steam&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;Group&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;steam&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;Type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;simple&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;WorkingDirectory&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;/opt/tf2classic/server&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;ExecStart&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;/bin/sh /opt/tf2classic/server/runserver.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;Restart&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;on-failure&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;RestartSec&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;[&lt;/span&gt;&lt;span class="z-entity z-name"&gt;Install&lt;/span&gt;&lt;span class="z-entity z-name"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-keyword"&gt;WantedBy&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adjust these if your setup differs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;User=&lt;/code&gt; and &lt;code&gt;Group=&lt;/code&gt; if your account name is not &lt;code&gt;steam&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WorkingDirectory=&lt;/code&gt; if SDK 2013 DS is elsewhere&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExecStart=&lt;/code&gt; if your script path is different&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Load and test:&lt;/p&gt;
&lt;pre class="giallo z-code"&gt;&lt;code data-lang="shellscript"&gt;&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; systemctl&lt;/span&gt;&lt;span class="z-string"&gt; daemon-reload&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; systemctl&lt;/span&gt;&lt;span class="z-string"&gt; start&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span class="z-entity z-name"&gt;sudo&lt;/span&gt;&lt;span class="z-string"&gt; systemctl&lt;/span&gt;&lt;span class="z-string"&gt; enable&lt;/span&gt;&lt;span class="z-string"&gt; tf2classic&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also replace &lt;code&gt;ExecStart=&lt;/code&gt; with your direct launch line, for example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ExecStart=/opt/tf2classic/server/srcds_run -console -game tf2classic +map pl_upward +maxplayers 24&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you want something more production-grade, check this AlliedModders thread:&lt;/p&gt;
&lt;p&gt;https://forums.alliedmods.net/showthread.php?t=273139&lt;/p&gt;</content></entry></feed>