ludic/packages/ludic.net/state.ludic
Orkuncakilkaya 71735b10a2 feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune
ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v),
q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding
facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)).

ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no
longer uses, nor anything it calls, and the argument that fills it - including an argument for a
parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is
told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would
make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 04:19:56 +03:00

128 lines
4.4 KiB
Text

# state.ludic - the wire's numbers, a peer, a queued message, what came in, and the session
export const NET_MTU: int = 1200
export const NET_PEERS: int = 12 # a host: slot 0 unused, a guest each after; a guest: 0 is the host
export const NET_TIMEOUT: int = 10 # seconds of silence before a peer is gone
export const NET_HELLO: int = 1 # the one kind a stranger may send a host; every other is the game's
const NET_BEAT: int = 0 # a heartbeat, never delivered
export const NET_IDLE: int = 0
export const NET_HOSTING: int = 1
export const NET_JOINING: int = 2
export const NET_JOINED: int = 3
export const NET_LOST: int = 4
# a message on its way out, kept until acknowledged when it is reliable
property NetMsg {
kind: int = 0,
rel: bool = false,
id: int = 0,
sent: float = 0.0, # net seconds it was last sent; -1 never
len: int = 0,
made: float = 0.0, # net seconds it was queued
data: []byte
}
property NetPeer {
on: bool = false,
ip: int = 0,
port: int = 0,
pid: int = 0,
heard: float = 0.0, # net seconds of the last packet from it
next_id: int = 1, # the next reliable id to send it
recv_id: int = 0, # the highest reliable id taken from it, in order
acked: int = 0, # the highest id it has taken from us
ack_due: bool = false,
queue: []NetMsg,
closing: bool = false, # let go once it has taken close_id
close_id: int = 0,
close_t: float = 0.0 # ... or at this net time, whichever comes first
}
# a message that came in, in order: read it with net_read(m) and nr_*
export property NetMessage {
slot: int = 0, # the peer slot it came from
from: int = 0, # the sender's pid, as its header says
kind: int = 0,
len: int = 0,
data: []byte
}
export state NetState {
net__cfg: NetConfig = null
net__facts: Queue<NetFact> = null
net__seen: []string = null # guests already punched for
net__punch_ip: words = null
net__punch_port: words = null
net__punch_left: words = null
net__punch_t: float = 0.0
net__punch_b: []byte = null # the punch itself, "MP" and two zeros, made once
net__relay_ip: int = 0
net__relay_port: int = 0
net__via_relay: bool = false # a guest talking to its host through the relay
net__from_ip: int = 0
net__from_port: int = 0
net__r_state: int = 0
net__r_role: int = 0 # 1 host, 2 guest
net__r_t: float = 0.0
net__r_tries: int = 0
net__pub_ip: int = 0
net__pub_port: int = 0
net__room: string = "" # the host's room code, or the one a guest asked for
net__http: int = 0
net__poll_t: float = 0.0
net__relay_t: float = 0.0
net__dial_heard: float = 0.0
net__why: int = 0
net__state: int = 0
net__sock: int = 0
net__time: float = 0.0
net__token: int = 0
net__my_pid: int = 0
net__next_pid: int = 2
net__peers: []NetPeer = null
net__in: []byte = null
net__out: []byte = null
net__wb: []byte = null # the message being written
net__wl: int = 0
net__rb: []byte = null # the message being read
net__rl: int = 0
net__rp: int = 0
net__rbad: bool = false
net__tb: []byte = null # text read out of a message, through one scratch buffer
net__hello_b: []byte = null # the game's hello, sent again on every dial
net__hello_l: int = 0
net__hello_t: float = 0.0 # seconds since it went; -1 not yet
net__wait_more: int = 0 # extra seconds a slow host is given (a map switch, a matchmaker)
net__beat_t: float = 0.0
net__join_ip: int = 0
net__join_port: int = 0
net__code_ip: int = 0
net__code_port: int = 0
net__bytes_out: int = 0
net__kind_out: words = null
net__inbox: Queue<NetMessage> = null
net__stun_ip: int = 0
net__stun_port: int = 0
net__txn: words = null
net__dice: Rng = null
}
export function net_inbox(net_st: mut NetState) -> Queue<NetMessage> {
if net_st.net__inbox == null { net_st.net__inbox = queue_new("net.inbox") }
return net_st.net__inbox
}
function net__init(net_st: mut NetState) -> void {
if net_st.net__peers != null { return }
net_st.net__peers = new []NetPeer
for i in 0 .. NET_PEERS {
let p = new NetPeer
p.queue = new []NetMsg
push(net_st.net__peers, p)
}
net_st.net__in = buffer(NET_MTU + 64)
net_st.net__out = buffer(NET_MTU + 64)
net_st.net__wb = buffer(NET_MTU)
net_st.net__rb = buffer(NET_MTU)
net_st.net__hello_b = buffer(NET_MTU)
}