← Home SEEBIE90 DOCS
The RIM-116 & Phalanx mod is published under the Arma Public License (APL)Example code is free to useSuggestions: Discord to the author

RIM-116 & Phalanx

Radar warning receiver

Three warning stages, derived from what the radar actually does. The search ping costs no network traffic at all – a whole run-in is a handful of messages.

In plain wordsThe pilot hears a ping each time the radar dish sweeps past, a steady tone once a mount holds the lock, and a loud alarm when a missile is away.

Three stages

StageWhat the pilot hearsWhere it comes from
SEARCHOne ping per dish revolution, louder the closer the radarComputed on the client from the shared bearing formula
LOCKSteady tone while a mount holds the trackOne server message, refreshed periodically
LAUNCHLoud two-tone alarmOne server message

The ping interval is constant, because it comes from the revolution and not from the range. Closer means louder, not faster.

Compute the ping, do not poll for it

Instead of repeatedly asking “is the beam on me now”, the client works out when it will be. That is not only cheaper, it is the only thing that works: a beam a few degrees wide stands on any one point for a few tens of milliseconds. Anything polling at a quarter of a second misses passes regularly.

Example code – free to use
float MyAD_Rwr_SecondsUntilBeam(MyAD_Radar radar, vector me)
{
	vector to = me - radar.GetOwner().GetOrigin();

	// Atan2(x, z): zero points to +Z, increasing towards +X
	float toMe = SCR_Math.fmod(Math.Atan2(to[0], to[2]) * Math.RAD2DEG, 360.0);
	float rest = SCR_Math.fmod(toMe - radar.Bearing(), 360.0);

	// already inside the beam: the pass is NOW, not one full turn away
	if (rest > 360.0 - radar.BeamWidth() * 0.5)
		return 0;

	return rest / radar.DegreesPerSecond();
}
Client reads radar positions from the registry→Computes the bearing from the time of day→Schedules its own next ping→No server involved

Refresh interval versus hold time

The server refreshes the lock now and then, and the receiver keeps it alive for a while without a refresh. The refresh interval must stay below the hold time, or the tone lapses between two perfectly healthy messages.

Two sound handles, not one switched channel

Sharing one handle between the lock tone and the launch alarm means the lock ends when the alarm starts – the opposite of what a pilot needs. While the lock tone is still there, another launch can be expected. Give each its own handle and let them mix.

Example code – free to use
void MyAD_Rwr_UpdateTones()
{
	bool wantLock = m_State != MyAD_ERwr.OFF;
	bool wantAlarm = m_State == MyAD_ERwr.LAUNCH;

	Sync(wantLock, m_hLock, "LOCK");
	Sync(wantAlarm, m_hAlarm, "ALARM");		// independent of the lock tone
}

void Sync(bool want, out AudioHandle handle, string event)
{
	if (want && handle == AudioHandle.Invalid)
		handle = PlayEvent(event);
	else if (!want && handle != AudioHandle.Invalid)
	{
		StopEvent(handle);
		handle = AudioHandle.Invalid;
	}
}
PitfallLoudness normalisation in an audio project is a volume lever above Volume 0. Changing the amplitude config of one event and not the others silently reorders the whole mix – a lock tone once ended up quieter than the pings it was meant to sit under.
NoteonRplName does not fire on the authority. A method that reacts to a replicated field has to be called on both paths, or the host behaves differently from every client – and on a listen server that is invisible until someone else joins.
Example code on this page is free to use in your own projects (credit appreciated). The RIM-116 & Phalanx mod is published under the Arma Public License (APL). Suggestions: Discord. Arma Reforger / Enfusion are trademarks of Bohemia Interactive.
Impressum · Privacy Policy