Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 49 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,73 @@
[Our Discord](https://discord.townofus.pl)
<div align="center">

# AleLuduMod
This mod unlocks the possibility to show more than 15 players on screen during an emergency meeting, on vitals, and on the Transporter/Glitch screen.

[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5662f6?style=for-the-badge&logo=discord&logoColor=white)](https://discord.townofus.pl)
[![Download](https://img.shields.io/badge/Download-Latest-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/raspberrygitq/AleLuduMod/releases/latest)

![GitHub Downloads](https://img.shields.io/github/downloads/raspberrygitq/AleLuduMod/total.svg?style=flat-square)
![GitHub Release](https://img.shields.io/github/release/raspberrygitq/AleLuduMod.svg?style=flat-square)

</div>

#
This mod unlocks the possibility to show more than 15 players on screen during an meeting hud, vitals and shapeshifter menu.

Works on **latest** Among Us Steam version.

> [!Warning]
> AleLuduMod **doesn't** work with official servers from Innersloth. It is recommended to use modded servers.

## Presentation

![AleLuduModEmergencyMeeting](https://github.com/townofus-pl/AleLuduMod/blob/main/aleludumeeting.png)

## Versions
| Mod version | Downloads | Notes |
|-------------|---------------------------------------------------------------------------------------------|-------|
| v1.0.6 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.6/AleLuduMod.dll) | |
| v1.0.5.beta | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.5.beta/AleLuduMod.dll) | Doesn't include creating 15+ players lobby. |
| v1.0.4 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.4/AleLuduMod.dll) | |
| v1.0.3 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.3/AleLuduMod.dll) | |
| v1.0.2 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.2/AleLuduMod.dll) | |
| v1.0.1 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.1/AleLuduMod.dll) | |
| v1.0.0 | [GitHub](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.0/AleLuduMod.dll) | |

| Mod Version | Among Us - Version | Downloads |
|-------------|--------------------|-------------------------------------------------------------------------------------------------|
| v1.1.2 | 17.0.0 - 17.2.2 | [Download](https://github.com/raspberrygitq/AleLuduMod/releases/download/v1.1.2/AleLuduMod.dll) |
| v1.1.1 | 17.0.0 - 17.2.1 | [Download](https://github.com/raspberrygitq/AleLuduMod/releases/download/v1.1.1/AleLuduMod.dll) |
| v1.1.0 | 16.0.0 - 16.1.0 | [Download](https://github.com/raspberrygitq/AleLuduMod/releases/download/v1.1.0/AleLuduMod.dll) |

<details>
<summary> Archive </summary>

| Mod version | Among Us - Version | Downloads |
|-------------|--------------------|---------------------------------------------------------------------------------------------|
| v1.0.6 | 16.0.2 - 16.1.0 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.6/AleLuduMod.dll) |
| v1.0.5.beta | 16.0.0 - 16.0.2 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.5.beta/AleLuduMod.dll) |
| v1.0.4 | 2024.11.26 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.4/AleLuduMod.dll) |
| v1.0.3 | 2024.11.26 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.3/AleLuduMod.dll) |
| v1.0.2 | 2024.11.26 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.2/AleLuduMod.dll) |
| v1.0.1 | 2024.11.26 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.1/AleLuduMod.dll) |
| v1.0.0 | 2024.11.26 | [Download](https://github.com/townofus-pl/AleLuduMod/releases/download/v1.0.0/AleLuduMod.dll) |
</details>

## Installation
Drop it into `\BepInEx\plugins\` folder inside your Among Us + TownOfUs folder installation.
Drop `AleLuduMod.dll` it the **`BepInEx\plugins`** folder with other mods or download the zip package.
> [!Warning]
> The mod needs [BepInEx](https://builds.bepinex.dev/projects/bepinex_be) and [Reactor](https://github.com/nuclearpowered/reactor) to work properly. While **BepInEx** is used by every mod and shouldn't be a problem, without **Reactor** you can't launch the mod.

## Mod Compatibility

AleLuduMod should be compatible with most mods that don't significantly alter interface in the meetings / vitals / shapeshifter menus.
> [!Caution]
> Host-only mods that use code from CrowdedMod are incompatible. CrowdedMod itself is **incompatible** with AleLuduMod because it modifies the interface in the same way as AleLuduMod.

## Commands
- `!limit <number>` - Set the maximum number of players in lobby (from 4 to 35).

## Authors
- [TownOfUs.pl](http://townofus.pl/)
- [TownOfUs.pl](https://townofus.pl/)
- OrzechMC
- Bubeu
- gitq

## Credits
- [CrowdedMods](https://github.com/CrowdedMods/CrowdedMod) - current authors of CrowdedMod that we used as a base for our mod
- [andry08/100-player-mod](https://github.com/andry08/100-player-mod) - original author of the CrowdedMod plugin (andry08)

---
> This mod is not affiliated with Among Us or Innersloth LLC, and the content contained therein is not endorsed or otherwise sponsored by Innersloth LLC. Portions of the materials contained herein are property of Innersloth LLC.\
> © Innersloth LLC.\
> [License](./LICENSE)
13 changes: 9 additions & 4 deletions src/AleLuduMod/AleLuduMod.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.1.0</Version>
<Version>1.1.2</Version>
<Authors>townofus.pl, OrzechMC, Bubeu, gitq</Authors>

<LangVersion>latest</LangVersion>
Expand All @@ -11,16 +11,21 @@
</PropertyGroup>
<PropertyGroup>
<GamePlatform Condition="'$(GamePlatform)' == ''">Steam</GamePlatform>
<GameVersion>2025.3.25</GameVersion>
<GameVersion>2025.9.9</GameVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Reactor" Version="2.4.0-ci.344" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.733" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" />
<PackageReference Include="AmongUs.GameLibs.$(GamePlatform)" Version="$(GameVersion)" PrivateAssets="all" />

<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.0.1" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="modinfo.json"/>
<EmbeddedResource Include="Resources\**\*.*"/>
</ItemGroup>

<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
Expand Down
20 changes: 9 additions & 11 deletions src/AleLuduMod/AleLuduModPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
using AmongUs.GameOptions;
using BepInEx;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Reactor;
using BepInEx.Configuration;
using System.Linq;
using Reactor.Utilities;

namespace AleLuduMod;

[BepInAutoPlugin("pl.townofus.aleludu")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
[BepInDependency("gg.reactor.debugger", BepInDependency.DependencyFlags.SoftDependency)] // fix debugger overwriting MinPlayers
[BepInDependency("com.slushiegoose.townofus", BepInDependency.DependencyFlags.SoftDependency)] // load after town of us
public partial class AleLuduModPlugin : BasePlugin
{
public const int MaxPlayers = 36;
public const int MaxImpostors = 36 / 2;
public const int MaxPlayers = 35;
public const int MaxImpostors = MaxPlayers / 2;
public static ConfigEntry<bool> Force4Columns { get; set; }
private Harmony Harmony { get; } = new(Id);

public override void Load()
{
NormalGameOptionsV09.RecommendedImpostors = NormalGameOptionsV09.MaxImpostors = Enumerable.Repeat(36, 36).ToArray();
NormalGameOptionsV09.MinPlayers = Enumerable.Repeat(4, 36).ToArray();
HideNSeekGameOptionsV09.MinPlayers = Enumerable.Repeat(4, 36).ToArray();
{
ReactorCredits.Register<AleLuduModPlugin>(ReactorCredits.AlwaysShow);

IL2CPPChainloader.Instance.Finished += ModCompatibility.Initialize;

Force4Columns = Config.Bind("Settings", "Force 4 columns", true, "Always display 4 columns in meeting, vitals, etc.");

Expand Down
29 changes: 8 additions & 21 deletions src/AleLuduMod/Components/MeetingHudBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,29 @@ namespace AleLuduMod.Components;
[RegisterInIl2Cpp]
public class MeetingHudBehaviour : MonoBehaviour
{
public MeetingHudBehaviour(IntPtr ptr) : base(ptr)
{
}

public MeetingHudBehaviour(IntPtr ptr) : base(ptr) { }
internal MeetingHud meetingHud = null!;

[HideFromIl2Cpp]
public IEnumerable<PlayerVoteArea> Targets => meetingHud.playerStates.OrderBy(p => p.AmDead);

public void Start()
{

if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value)
{
// dont change layout if players count is below 16
return;
}

if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value) return; // dont change layout if players count is below 16
var i = 0;
foreach (var button in Targets)
{

button.gameObject.SetActive(true);

var row = i / 4;
var col = i % 4;
var buttonTransform = button.transform;
buttonTransform.localScale *= 0.75f;
buttonTransform.localPosition = meetingHud.VoteOrigin +
new Vector3(
meetingHud.VoteButtonOffsets.x * col * 0.75f - 0.375f,
meetingHud.VoteButtonOffsets.y * row * 0.75f,
buttonTransform.localPosition.z
);
buttonTransform.localPosition = meetingHud.VoteOrigin + new Vector3(
meetingHud.VoteButtonOffsets.x * col * 0.75f - 0.375f,
meetingHud.VoteButtonOffsets.y * row * 0.75f,
buttonTransform.localPosition.z
);
i++;
}
}

}
}
26 changes: 9 additions & 17 deletions src/AleLuduMod/Components/ShapeshifterMenuBehaviour.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
using System;
using Il2CppInterop.Runtime.Attributes;
using Reactor.Utilities.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using Il2CppInterop.Runtime.Attributes;
using Reactor.Utilities.Attributes;
using UnityEngine;

namespace AleLuduMod.Components;

[RegisterInIl2Cpp]
public class ShapeshifterBehaviour : MonoBehaviour
{
public ShapeshifterBehaviour(IntPtr ptr) : base(ptr)
{
}
public ShapeshifterBehaviour(IntPtr ptr) : base(ptr) { }
internal ShapeshifterMinigame shapeshifterMinigame = null!;

public ShapeshifterMinigame shapeshifterMinigame = null!;
[HideFromIl2Cpp] public IEnumerable<ShapeshifterPanel> Targets => shapeshifterMinigame.potentialVictims.ToArray();
[HideFromIl2Cpp]
public IEnumerable<ShapeshifterPanel> Targets => shapeshifterMinigame.potentialVictims.ToArray();

public void Start()
{
if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value)
{
// dont change layout if players count is below 16
return;
}

if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value) return; // dont change layout if players count is below 16
var i = 0;

foreach (var panel in Targets)
{
panel.gameObject.SetActive(true);

var row = i / 4;
var col = i % 4;
var buttonTransform = panel.transform;
Expand All @@ -39,7 +31,7 @@ public void Start()
shapeshifterMinigame.XStart + shapeshifterMinigame.XOffset * col * 0.75f - 0.375f,
shapeshifterMinigame.YStart + shapeshifterMinigame.YOffset * row * 0.75f,
buttonTransform.localPosition.z
);
);
i++;
}
}
Expand Down
21 changes: 7 additions & 14 deletions src/AleLuduMod/Components/VitalsHudBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,15 @@ namespace AleLuduMod.Components;
[RegisterInIl2Cpp]
public class VitalsHudBehaviour : MonoBehaviour
{
public VitalsHudBehaviour(IntPtr ptr) : base(ptr) {}

public VitalsHudBehaviour(IntPtr ptr) : base(ptr) { }
internal VitalsMinigame vitalsMinigame = null!;

[HideFromIl2Cpp]
public IEnumerable<VitalsPanel> Targets => vitalsMinigame.vitals.ToArray();

public void Start()
{

if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value)
{
// dont change layout if players count is below 16
return;
}

if (Targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value) return; // dont change layout if players count is below 16
var i = 0;
foreach (var panel in Targets)
{
Expand All @@ -35,11 +28,11 @@ public void Start()
var panelTransform = panel.transform;
panelTransform.localScale *= 0.75f;
panelTransform.localPosition = new Vector3(
vitalsMinigame.XStart + vitalsMinigame.XOffset * (col * 0.75f - 0.25f),
vitalsMinigame.YStart + vitalsMinigame.YOffset * row * 0.75f,
panelTransform.localPosition.z
);
vitalsMinigame.XStart + vitalsMinigame.XOffset * (col * 0.75f - 0.25f),
vitalsMinigame.YStart + vitalsMinigame.YOffset * row * 0.75f,
panelTransform.localPosition.z
);
i++;
}
}
}
}
75 changes: 75 additions & 0 deletions src/AleLuduMod/ModCompatibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Reactor.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace AleLuduMod;

public static class ModCompatibility
{
public const string MiraApiGuid = "mira.api";
public static bool MiraApiLoaded { get; private set; }
private static BasePlugin MiraApiPlugin { get; set; }
private static Assembly MiraApiAssembly { get; set; }
private static Type[] MiraApiTypes { get; set; }
public static float XStart = -0.8f;
public static float YStart = 2.15f;
public static float XOffset = 1.95f;
public static float YOffset = -0.65f;

public static void Initialize()
{
InitMiraApi();
}

private static void InitMiraApi()
{
if (!IL2CPPChainloader.Instance.Plugins.TryGetValue(MiraApiGuid, out var value))
{
return;
}

MiraApiPlugin = (value.Instance as BasePlugin)!;
MiraApiAssembly = MiraApiPlugin.GetType().Assembly;

MiraApiTypes = AccessTools.GetTypesFromAssembly(MiraApiAssembly);

var playerMenu = MiraApiTypes.First(t => t.Name == "CustomPlayerMenu");
var menuBegin = AccessTools.Method(playerMenu, "Begin", new[] { typeof(Func<PlayerControl, bool>), typeof(Action<PlayerControl?>) });

var compatType = typeof(ModCompatibility);
var harmony = new Harmony("aleludu.miraapi.patch");
harmony.Patch(menuBegin, null,
new HarmonyMethod(AccessTools.Method(compatType, nameof(BeginPostfix))));

MiraApiLoaded = true;
Logger<AleLuduModPlugin>.Message("MiraAPI was detected and patched");
}
public static void BeginPostfix(dynamic __instance, Func<PlayerControl, bool> playerMatch, Action<PlayerControl?> onClick)
{
var targets = __instance.potentialVictims as List<ShapeshifterPanel>;
if (targets == null || targets.Count() < 16 && !AleLuduModPlugin.Force4Columns.Value) return;

var i = 0;

foreach (var panel in targets)
{
panel.gameObject.SetActive(true);

var row = i / 4;
var col = i % 4;
var buttonTransform = panel.transform;
buttonTransform.localScale *= 0.75f;
buttonTransform.localPosition = new Vector3(
XStart + XOffset * col * 1.1f - 2.4f,
YStart + YOffset * row * 0.9255f - 0.65f,
buttonTransform.localPosition.z
);
i++;
}
}
}
Loading