Soldier Front · Dragonfly, 2004 · Soldier Front Legacy by TeamVanilla, 2026

Build 1 · protocol 24

OpenSFSoldier Front Legacy
Contents

Docs Running a server

Packs

A server's own weapons, maps and characters: what a pack may do, pack.cfg, building with lsfpack, the names and limits, and what players see.

A server can add content of its own. Players download it from your server when they join, play with it there, and it is gone from their game when they leave. Everything here is checked by lsfpack when you build, by the server when it starts and by every player's game when it joins. A pack that breaks a rule is refused with the reason; nothing "mostly works".

What a pack can and cannot do

  • A pack adds. It never changes, replaces or re-skins anything of the base game: the AK-74 is the AK-74 on every server.
  • A pack is data only: models, textures, sounds, maps and the numbers in pack.cfg. No script, shader or program has a place in one.
  • What a pack adds exists only on your server. A player buys your weapon with SP in your server's shop and owns it there; it does not follow them elsewhere.
  • Your packs together may be 50 MB at most. Packs download only from your server itself.
  • When you register a server you confirm you may share every pack it serves. SFLegacy Staff can take down a pack that breaks that.

The folders

weapons/<pack>/pack.cfg     and the pack's files beside it
maps/<pack>/pack.cfg
chars/<pack>/pack.cfg
packs/                      what lsfpack builds: <pack>.lsfpack, served to players
tools/lsfpack               the builder

Each folder under weapons/, maps/ or chars/ becomes one pack. The files keep Soldier Front's own layout:

InLay your files out asThey go into
weapons/<pack>/bhw/sf_a_<gun>/...the weapon library
maps/<pack>/ground/sf_m_<map>/... and world/sf_m_<map>.wldthe area library
chars/<pack>/sf_c_<name>/...the force library

A top folder named area, weapon, force, sound, effect, lobby or menu puts what is under it into that library instead. File and folder names are lower-case letters, digits, _, - and . only.

pack.cfg

id = mypack              # lower-case letters, digits and _, 3 to 24: unique on your server
version = 1
author = "Who made it"

then a section for each thing the pack adds: [weapon], [character], [part] or [map].

A weapon

[weapon]
name  = longrifle            # its code is x:mypack:longrifle; players' ownership is kept by it
title = "Long Rifle"         # what players read
like  = ak74                 # the base gun it starts from
price = 12000                # SP; a custom item is never free
damage = 38
magazine = 20

like names a base gun by its model id (ak74, m4a1 and so on). Every number you do not give is that gun's, and so are its sounds, shop picture, HUD picture and kill mark. Leave model out and the weapon uses the like gun's model: a new gun made of numbers alone. To give it a model of its own, model = bhw/sf_a_longrifle and the gun's files in that folder, named as Soldier Front names them (the gun, its rig, the hands, a clip for each action, .sfc for where it sits in the view, .sfm for its clips' speeds).

KeyBound
classrifle, smg, sniper, machinegun, shotgun, pistol, knife or grenade. The slot follows the class
damage0 to 500, with head and leg multipliers
range, falloff_start, falloff_mincentimetres, and what is left of the damage at range
rpm, automatic1 to 1,200; yes or no
magazine, reserve0 to 300; 0 to 999
reload, drawseconds
spread_*, recoil_*the cone and the view's kick, standing, crouched, moving, running, in the air
move_speedhow fast its owner runs with it; too high and the server would refuse the movement, so it is refused here
grip1 to 7, 9 or 10: which arm clips the soldier holds it with
zoom, scope_image, scope_movea scope
pellets1 to 16
grenade, fuse, blast_radiusnone, frag, flash, smoke or gas; seconds; 0 to 2,000 cm
melee_rangea blade's reach
price1 to 10,000,000 SP

A map

[map]
name  = harbour              # its id is x-mypack-harbour (32 characters at most)
title = "Harbour"
night = false                # true for a map baked dark

with the map as SFMapEditor (or the original tools) makes it: its geometry (.map), its textures' table (.msf), its world script (.xml: spawns, objectives and the games it offers), collision (_c.cft), props (_obj.env), lightmaps and world/sf_m_<map>.wld. Textures and props found by name in the base game cost none of your 50 MB, so reuse them where you can.

When the pack is built the map is proved as the base maps are: it loads whole, every texture resolves, both sides have somewhere to spawn, there is collision to stand on and ground to walk, and its world script offers at least one game.

A character

[character]
name   = ranger
title  = "Ranger"
nation = "USA"
model  = sf_c_ranger         # the folder beside pack.cfg
art    = delta               # the base force whose HUD pictures and voice stand in
price  = 30000
speed  = 1.0                 # 0.8 to 1.04
upper_defense = 0            # 0 to 0.05, like lower_defense and avoid_headshot
  • A character is only a look. Every soldier is hit by the same boxes whatever the model, so one much bigger or smaller than the base soldiers is refused.
  • Its skeleton has at most 128 bones and uses the base soldiers' bone names, since the game plays the base soldiers' own motions on it. The bones, the size and the clips are measured from your model when the pack is built.

A part (a piece of clothing, an accessory) has a [part] section: its name, title, tab (Head, Face, Torso, Arms, Legs, Feet or Accessory), slot, the character it belongs to, its model and price. A pack character wears only its own pack's parts; a pack may also add a new part for a base force (force = delta): a new item, never a re-skin of an old one.

Building and checking

tools/lsfpack build --data data             builds every pack folder into packs/, checking each
tools/lsfpack check packs --data data       what the server will do when it starts
tools/lsfpack list packs/mypack.lsfpack     what a pack holds

Restart the server to serve new packs. A server's packs never change while it runs, so no player sees half of an update. A server that finds a broken pack in packs/ does not start, and says which and why.

Names and limits

  • Every file of a pack lives under x/<pack id>/ inside the game, so it can never take the place of a base file.
  • A file may not share its name with a base file (a picture counts under any extension), and two of your packs cannot ship the same new name. A map's lightmaps are free.
WhatLimit
A server's packs together50 MB
Files in a pack4,096
A file's name with its folders120 characters
A picture4,096 a side (2,048 for players on Android to be able to join)
A sound8 MB, .wav or .mp3
A skeleton128 bones

What players see

Joining your server, a player's game is told what your packs are and how big, and asks before downloading more than the player allows. It downloads them from your server (upload_kbps of your upload in all, max_downloaders players at a time, the rest waiting their turn), checks every one again, and only then enters. Packs are kept in the player's cache by their fingerprint, so the next join downloads nothing.

A match played with your packs is recorded with their fingerprints: the recording plays back only where those packs are.